diff --git a/.gitignore b/.gitignore
index 2d65135e7d..81317c33c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,6 +43,11 @@ tools/unit-test-app/build
tools/unit-test-app/builds
tools/unit-test-app/output
+# IDF monitor test
+tools/test_idf_monitor/outputs
+
+TEST_LOGS
+
# AWS IoT Examples require device-specific certs/keys
examples/protocols/aws_iot/*/main/certs/*.pem.*
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0f4d9d16be..4e5b1e3b8d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,9 +1,9 @@
stages:
- build
- assign_test
+ - host_test
- unit_test
- - test
- - test_report
+ - integration_test
- deploy
variables:
@@ -31,11 +31,25 @@ variables:
APPLY_BOT_FILTER_SCRIPT: "$CI_PROJECT_DIR/tools/ci/apply_bot_filter.py"
CHECKOUT_REF_SCRIPT: "$CI_PROJECT_DIR/tools/ci/checkout_project_ref.py"
+# When 'fetch' strategy is used, Gitlab removes untracked files before checking out
+# new revision. However if the new revision doesn't include some of the submodules
+# which were present in the old revision, such submodule directories would not be
+# removed by the checkout. This extra step ensures that these stale submodules
+# are removed.
+.git_clean_stale_submodules: &git_clean_stale_submodules >
+ find . -name '.git' -not -path './.git' -printf '%P\n'
+ | sed 's|/.git||'
+ | xargs -I {} sh -c '
+ grep -q {} .gitmodules
+ || (echo "Removing {}, has .git directory but not in .gitmodules file"
+ && rm -rf {});'
+
# before each job, we need to check if this job is filtered by bot stage/job filter
.apply_bot_filter: &apply_bot_filter
python $APPLY_BOT_FILTER_SCRIPT || exit 0
before_script:
+ - *git_clean_stale_submodules
# apply bot filter in before script
- *apply_bot_filter
# add gitlab ssh key
@@ -56,6 +70,7 @@ before_script:
.do_nothing_before:
before_script: &do_nothing_before
+ - *git_clean_stale_submodules
# apply bot filter in before script
- *apply_bot_filter
- echo "Not setting up GitLab key, not fetching submodules"
@@ -63,6 +78,7 @@ before_script:
.add_gitlab_key_before:
before_script: &add_gitlab_key_before
+ - *git_clean_stale_submodules
# apply bot filter in before script
- *apply_bot_filter
- echo "Not fetching submodules"
@@ -135,6 +151,8 @@ build_ssc_01:
build_ssc_02:
<<: *build_ssc_template
+# If you want to add new build ssc jobs, please add it into dependencies of `assign_test` and `.test_template`
+
build_esp_idf_tests:
<<: *build_template
artifacts:
@@ -142,14 +160,14 @@ build_esp_idf_tests:
- tools/unit-test-app/output
- components/idf_test/unit_test/TestCaseAll.yml
- components/idf_test/unit_test/CIConfigs/*.yml
- expire_in: 6 mos
+ expire_in: 1 mos
script:
- cd tools/unit-test-app
- - make help # make sure kconfig tools are built in single process
+ - MAKEFLAGS= make help # make sure kconfig tools are built in single process
- make ut-clean-all-configs
- export EXTRA_CFLAGS="-Werror -Werror=deprecated-declarations"
- export EXTRA_CXXFLAGS=${EXTRA_CFLAGS}
- - make ut-build-all-configs TESTS_ALL=1
+ - make ut-build-all-configs
- python tools/UnitTestParser.py
.build_examples_template: &build_examples_template
@@ -208,6 +226,7 @@ build_examples_06:
build_examples_07:
<<: *build_examples_template
+# If you want to add new build example jobs, please add it into dependencies of `.example_test_template`
build_docs:
stage: build
@@ -246,22 +265,21 @@ verify_cmake_style:
script:
tools/cmake/run_cmake_lint.sh
-test_nvs_on_host:
- stage: test
+.host_test_template: &host_test_template
+ stage: host_test
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- host_test
dependencies: []
+
+test_nvs_on_host:
+ <<: *host_test_template
script:
- cd components/nvs_flash/test_nvs_host
- make test
test_nvs_coverage:
- stage: test
- image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
- tags:
- - host_test
- dependencies: []
+ <<: *host_test_template
artifacts:
paths:
- components/nvs_flash/test_nvs_host/coverage_report
@@ -275,52 +293,73 @@ test_nvs_coverage:
- make coverage_report
test_partition_table_on_host:
- stage: test
- image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
+ <<: *host_test_template
tags:
- build
- dependencies: []
script:
- cd components/partition_table/test_gen_esp32part_host
- ./gen_esp32part_tests.py
test_wl_on_host:
- stage: test
- image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
- tags:
- - host_test
+ <<: *host_test_template
artifacts:
paths:
- components/wear_levelling/test_wl_host/coverage_report.zip
- dependencies: []
script:
- cd components/wear_levelling/test_wl_host
- make test
-test_multi_heap_on_host:
- stage: test
- image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
+test_fatfs_on_host:
+ <<: *host_test_template
+ script:
+ - cd components/fatfs/test_fatfs_host/
+ - make test
+
+test_mdns_fuzzer_on_host:
+ stage: host_test
+ image: $CI_DOCKER_REGISTRY/afl-fuzzer-test
tags:
- host_test
+ dependencies: []
+ artifacts:
+ when: always
+ paths:
+ - components/mdns/test_afl_fuzz_host/out/crashes
+ expire_in: 1 mos
+ only:
+ # can only be triggered
+ - triggers
+ variables:
+ BOT_NEEDS_TRIGGER_BY_NAME: 1
+ script:
+ - export AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 && export AFL_SKIP_CPUFREQ=1
+ - cd components/mdns/test_afl_fuzz_host/
+ # run AFL fuzzer for one hour
+ - ( make fuzz || pkill sleep ) &
+ - ( sleep 3600 || mkdir -p out/crashes/env_failed ) && pkill afl-fuz
+ # check no crashes found
+ - "[ -z `ls out/crashes/` ] || exit 1"
+
+test_spiffs_on_host:
+ <<: *host_test_template
+ script:
+ - cd components/spiffs/test_spiffs_host/
+ - make test
+
+test_multi_heap_on_host:
+ <<: *host_test_template
script:
- cd components/heap/test_multi_heap_host
- ./test_all_configs.sh
test_confserver:
- stage: test
- image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
- tags:
- - host_test
+ <<: *host_test_template
script:
- cd tools/kconfig_new/test
- ./test_confserver.py
test_build_system:
- stage: test
- image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
- tags:
- - host_test
- dependencies: []
+ <<: *host_test_template
script:
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
- rm -rf test_build_system
@@ -329,11 +368,7 @@ test_build_system:
- ${IDF_PATH}/tools/ci/test_build_system.sh
test_build_system_cmake:
- stage: test
- image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
- tags:
- - host_test
- dependencies: []
+ <<: *host_test_template
script:
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
- rm -rf test_build_system
@@ -341,73 +376,25 @@ test_build_system_cmake:
- cd test_build_system
- ${IDF_PATH}/tools/ci/test_build_system_cmake.sh
-test_report:
- stage: test_report
- image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
- tags:
- - report
- only:
- - master
- - triggers
- - schedules
- - /^release\/v/
- - /^v\d+\.\d+(\.\d+)?($|-)/
- variables:
- LOG_PATH: "$CI_PROJECT_DIR/$CI_COMMIT_SHA"
- TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test"
- REPORT_PATH: "$CI_PROJECT_DIR/CI_Test_Report"
- MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/tools/unit-test-app/tools/ModuleDefinition.yml"
- #dependencies:
- #We need all UT* and IT* artifacts except for only a few other
+test_idf_monitor:
+ <<: *host_test_template
artifacts:
- when: always
+ when: on_failure
paths:
- - $REPORT_PATH
- - $LOG_PATH
- expire_in: 12 mos
+ - tools/test_idf_monitor/outputs/*
+ expire_in: 1 week
script:
- # calc log path
- - VER_NUM=`git rev-list HEAD | wc -l | awk '{print $1}'`
- - SHA_ID=`echo $CI_COMMIT_SHA | cut -c 1-7`
- - REVISION="${VER_NUM}_${SHA_ID}"
- # replace / to _ in branch name
- - ESCAPED_BRANCH_NAME=`echo $CI_COMMIT_REF_NAME | sed 's/\//___/g'`
- # result path and artifacts path
- - RESULT_PATH="$CI_PROJECT_NAME/$ESCAPED_BRANCH_NAME/$REVISION"
- - ARTIFACTS_PATH="$GITLAB_HTTP_SERVER/idf/esp-idf/builds/$CI_JOB_ID/artifacts/browse/$CI_COMMIT_SHA"
- # clone test bench
- - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
- - cd auto_test_script
- - python $CHECKOUT_REF_SCRIPT auto_test_script
- # generate report
- - TEST_RESULT=Pass
- - python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH -r $RESULT_PATH -a $ARTIFACTS_PATH -m $MODULE_UPDATE_FILE || TEST_RESULT=Fail
- # commit to CI-test-result project
- - git clone $GITLAB_SSH_SERVER/qa/CI-test-result.git
- - rm -rf "CI-test-result/RawData/$RESULT_PATH"
- - cp -R $CI_PROJECT_NAME CI-test-result/RawData
- - cd CI-test-result
- # config git user
- - git config --global user.email "ci-test-result@espressif.com"
- - git config --global user.name "ci-test-result"
- # commit test result
- - git add .
- - git commit . -m "update test result for $CI_PROJECT_NAME/$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA, pipeline ID $CI_PIPELINE_ID" || exit 0
- - git push origin master
- - test "${TEST_RESULT}" = "Pass" || exit 1
+ - cd ${IDF_PATH}/tools/test_idf_monitor
+ - ./run_test_idf_monitor.py
test_esp_err_to_name_on_host:
- stage: test
- image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
- tags:
- - build
- dependencies: []
+ <<: *host_test_template
script:
- cd tools/
- ./gen_esp_err_to_name.py
- git diff --exit-code -- ../components/esp32/esp_err_to_name.c || (echo 'Differences found. Please run gen_esp_err_to_name.py and commit the changes.'; exit 1)
-push_master_to_github:
+push_to_github:
stage: deploy
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
@@ -416,11 +403,8 @@ push_master_to_github:
- master
- /^release\/v/
- /^v\d+\.\d+(\.\d+)?($|-)/
- - feature/cmake
when: on_success
dependencies: []
- variables:
- GITHUB_PUSH_REFS: refs/remotes/origin/release refs/remotes/origin/master refs/remotes/origin/feature/cmake
before_script: *do_nothing_before
script:
- mkdir -p ~/.ssh
@@ -431,15 +415,12 @@ push_master_to_github:
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
- git remote remove github &>/dev/null || true
- git remote add github git@github.com:espressif/esp-idf.git
- # What the next line of script does: goes through the list of refs for all branches we push to github,
- # generates a snippet of shell which is evaluated. The snippet checks CI_COMMIT_SHA against the SHA
- # (aka objectname) at tip of each branch, and if any SHAs match then it checks out the local branch
- # and then pushes that ref to a corresponding github branch
- - eval $(git for-each-ref --shell bash --format 'if [ $CI_COMMIT_SHA == %(objectname) ]; then git checkout -B %(refname:strip=3); git push --follow-tags github %(refname:strip=3); fi;' $GITHUB_PUSH_REFS)
-
+ # Need separate push commands for tag builds and for branch builds
+ - "[ -n \"${CI_COMMIT_TAG}\" ] && git push github ${CI_COMMIT_TAG}"
+ - "[ -z \"${CI_COMMIT_TAG}\" ] && git push github ${CI_COMMIT_SHA}:refs/heads/${CI_COMMIT_REF_NAME}"
deploy_docs:
- stage: assign_test
+ stage: host_test
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- deploy
@@ -474,7 +455,7 @@ deploy_docs:
- echo "[document preview][zh_CN] $CI_DOCKER_REGISTRY/docs/esp-idf/zh_CN/${GIT_VER}/index.html"
check_doc_links:
- stage: test
+ stage: host_test
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
tags:
- check_doc_links
@@ -493,6 +474,20 @@ check_doc_links:
- cd docs
- make linkcheck
+check_line_endings:
+ stage: deploy
+ image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
+ tags:
+ - build
+ except:
+ - master
+ - /^release\/v/
+ - /^v\d+\.\d+(\.\d+)?($|-)/
+ dependencies: []
+ before_script: *do_nothing_before
+ script:
+ - tools/ci/check-line-endings.sh ${IDF_PATH}
+
check_commit_msg:
stage: deploy
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
@@ -544,7 +539,7 @@ check_submodule_sync:
assign_test:
tags:
- assign_test
- image: $CI_DOCKER_REGISTRY/ubuntu-test-env$BOT_DOCKER_IMAGE_TAG
+ image: $CI_DOCKER_REGISTRY/ubuntu-test-env
stage: assign_test
# gitlab ci do not support match job with RegEx or wildcard now in dependencies.
# we have a lot build example jobs. now we don't use dependencies, just download all artificats of build stage.
@@ -576,7 +571,7 @@ assign_test:
- python CIAssignTestCases.py -t $IDF_PATH/components/idf_test/integration_test -c $IDF_PATH/.gitlab-ci.yml -b $IDF_PATH/SSC/ssc_bin
.example_test_template: &example_test_template
- stage: test
+ stage: integration_test
when: on_success
only:
- master
@@ -584,14 +579,21 @@ assign_test:
- /^v\d+\.\d+(\.\d+)?($|-)/
- triggers
- schedules
- # gitlab ci do not support match job with RegEx or wildcard now in dependencies.
- # we have a lot build example jobs and the binaries them exceed the limitation of artifacts.
- # we can't artifact them in one job. For example test jobs, download all artifacts from previous stages.
+ dependencies:
+ - assign_test
+ - build_examples_00
+ - build_examples_01
+ - build_examples_02
+ - build_examples_03
+ - build_examples_04
+ - build_examples_05
+ - build_examples_06
+ - build_examples_07
artifacts:
when: always
paths:
- $LOG_PATH
- expire_in: 6 mos
+ expire_in: 1 mos
variables:
TEST_FW_PATH: "$CI_PROJECT_DIR/tools/tiny-test-fw"
TEST_CASE_PATH: "$CI_PROJECT_DIR/examples"
@@ -623,7 +625,7 @@ assign_test:
ENV_FILE: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/EnvConfig.yml"
.test_template: &test_template
- stage: test
+ stage: integration_test
when: on_success
only:
- master
@@ -631,7 +633,6 @@ assign_test:
- /^v\d+\.\d+(\.\d+)?($|-)/
- triggers
- schedules
- allow_failure: true
dependencies:
- assign_test
- build_ssc_00
@@ -641,7 +642,7 @@ assign_test:
when: always
paths:
- $LOG_PATH
- expire_in: 6 mos
+ expire_in: 1 mos
variables:
LOCAL_ENV_CONFIG_PATH: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF"
LOG_PATH: "$CI_PROJECT_DIR/$CI_COMMIT_SHA"
@@ -670,7 +671,7 @@ nvs_compatible_test:
paths:
- $LOG_PATH
- nvs_wifi.bin
- expire_in: 6 mos
+ expire_in: 1 mos
tags:
- ESP32_IDF
- NVS_Compatible
@@ -700,6 +701,18 @@ example_test_002_01:
- ESP32
- Example_ShieldBox
+example_test_003_01:
+ <<: *example_test_template
+ tags:
+ - ESP32
+ - Example_SDIO
+
+example_test_004_01:
+ <<: *example_test_template
+ tags:
+ - ESP32
+ - Example_CAN
+
UT_001_01:
<<: *unit_test_template
tags:
@@ -844,6 +857,66 @@ UT_001_24:
- ESP32_IDF
- UT_T1_1
+UT_001_25:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+
+UT_001_26:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+
+UT_001_27:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+
+UT_001_28:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+
+UT_001_29:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+
+UT_001_30:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+
+UT_001_31:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+
+UT_001_32:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+
+UT_001_33:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+
+UT_001_34:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+
UT_002_01:
<<: *unit_test_template
tags:
@@ -936,6 +1009,27 @@ UT_004_08:
- UT_T1_1
- psram
+UT_004_09:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+ - psram
+
+UT_004_10:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+ - psram
+
+UT_004_11:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+ - psram
+
UT_005_01:
<<: *unit_test_template
tags:
@@ -950,6 +1044,112 @@ UT_005_02:
- UT_T1_SPIMODE
- psram
+UT_006_01:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_GPIO
+
+UT_006_02:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_GPIO
+
+UT_006_03:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_GPIO
+
+UT_006_04:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_GPIO
+ - psram
+
+UT_007_01:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_PCNT
+
+UT_007_02:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_PCNT
+
+UT_007_03:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_PCNT
+
+UT_007_04:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_PCNT
+ - psram
+
+UT_008_01:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_LEDC
+
+UT_008_02:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_LEDC
+
+UT_008_03:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_LEDC
+
+UT_008_04:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_LEDC
+ - psram
+
+UT_010_01:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_RMT
+
+UT_010_02:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_RMT
+
+UT_010_03:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_RMT
+
+UT_010_04:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_RMT
+ - psram
+
+UT_601_01:
+ <<: *unit_test_template
+ tags:
+ - ESP32_IDF
+ - UT_T1_1
+
IT_001_01:
<<: *test_template
tags:
@@ -1118,6 +1318,12 @@ IT_010_01:
- ESP32_IDF
- SSC_T5_1
+IT_011_01:
+ <<: *test_template
+ tags:
+ - ESP32_IDF
+ - SSC_T50_1
+
IT_501_01:
<<: *test_template
tags:
diff --git a/.gitmodules b/.gitmodules
index 849ef99043..2a9eaef010 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -41,3 +41,11 @@
[submodule "components/mbedtls/mbedtls"]
path = components/mbedtls/mbedtls
url = https://github.com/espressif/mbedtls.git
+
+[submodule "components/asio/asio"]
+ path = components/asio/asio
+ url = https://github.com/espressif/asio.git
+
+[submodule "components/expat/expat"]
+ path = components/expat/expat
+ url = https://github.com/libexpat/libexpat.git
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 19dde17a9e..3a9bd581da 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -25,6 +25,8 @@ Before sending us a Pull Request, please consider this list of points:
* Are comments and documentation written in clear English, with no spelling or grammar errors?
+* Example contributions are also welcome. Please check the :doc:`creating-examples` guide for these.
+
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" `squashed into previous commits `_?
* If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback.
@@ -51,5 +53,6 @@ Related Documents
style-guide
documenting-code
+ creating-examples
../api-reference/template
- contributor-agreement
\ No newline at end of file
+ contributor-agreement
diff --git a/Kconfig b/Kconfig
index f6ebbc5731..76a9e57c34 100644
--- a/Kconfig
+++ b/Kconfig
@@ -42,137 +42,7 @@ endmenu # SDK tool configuration
source "$COMPONENT_KCONFIGS_PROJBUILD"
-menu "Compiler options"
-
-choice OPTIMIZATION_COMPILER
- prompt "Optimization Level"
- default OPTIMIZATION_LEVEL_DEBUG
- help
- This option sets compiler optimization level (gcc -O argument).
-
- - for "Release" setting, -Os flag is added to CFLAGS.
- - for "Debug" setting, -Og flag is added to CFLAGS.
-
- "Release" with -Os produces smaller & faster compiled code but it
- may be harder to correlated code addresses to source files when debugging.
-
- To add custom optimization settings, set CFLAGS and/or CPPFLAGS
- in project makefile, before including $(IDF_PATH)/make/project.mk. Note that
- custom optimization levels may be unsupported.
-
-config OPTIMIZATION_LEVEL_DEBUG
- bool "Debug (-Og)"
-config OPTIMIZATION_LEVEL_RELEASE
- bool "Release (-Os)"
-endchoice
-
-choice OPTIMIZATION_ASSERTION_LEVEL
- prompt "Assertion level"
- default OPTIMIZATION_ASSERTIONS_ENABLED
- help
- Assertions can be:
- - Enabled. Failure will print verbose assertion details. This is the default.
-
- - Set to "silent" to save code size (failed assertions will abort() but user
- needs to use the aborting address to find the line number with the failed assertion.)
-
- - Disabled entirely (not recommended for most configurations.) -DNDEBUG is added
- to CPPFLAGS in this case.
-
-config OPTIMIZATION_ASSERTIONS_ENABLED
- prompt "Enabled"
- bool
- help
- Enable assertions. Assertion content and line number will be printed on failure.
-
-config OPTIMIZATION_ASSERTIONS_SILENT
- prompt "Silent (saves code size)"
- bool
- help
- Enable silent assertions. Failed assertions will abort(), user needs to
- use the aborting address to find the line number with the failed assertion.
-
-config OPTIMIZATION_ASSERTIONS_DISABLED
- prompt "Disabled (sets -DNDEBUG)"
- bool
- help
- If assertions are disabled, -DNDEBUG is added to CPPFLAGS.
-
-endchoice # assertions
-
-menuconfig CXX_EXCEPTIONS
- bool "Enable C++ exceptions"
- default n
- help
- Enabling this option compiles all IDF C++ files with exception support enabled.
-
- Disabling this option disables C++ exception support in all compiled files, and any libstdc++ code which throws
- an exception will abort instead.
-
- Enabling this option currently adds an additional ~500 bytes of heap overhead
- when an exception is thrown in user code for the first time.
-
-config CXX_EXCEPTIONS_EMG_POOL_SIZE
- int "Emergency Pool Size"
- default 0
- depends on CXX_EXCEPTIONS
- help
- Size (in bytes) of the emergency memory pool for C++ exceptions. This pool will be used to allocate
- memory for thrown exceptions when there is not enough memory on the heap.
-
-choice STACK_CHECK_MODE
- prompt "Stack smashing protection mode"
- default STACK_CHECK_NONE
- help
- Stack smashing protection mode. Emit extra code to check for buffer overflows, such as stack
- smashing attacks. This is done by adding a guard variable to functions with vulnerable objects.
- The guards are initialized when a function is entered and then checked when the function exits.
- If a guard check fails, program is halted. Protection has the following modes:
-
- - In NORMAL mode (GCC flag: -fstack-protector) only functions that call
- alloca, and functions with buffers larger than 8 bytes are protected.
- - STRONG mode (GCC flag: -fstack-protector-strong) is like NORMAL, but
- includes additional functions to be protected -- those that have
- local array definitions, or have references to local frame addresses.
- - In OVERALL mode (GCC flag: -fstack-protector-all) all functions are
- protected.
-
- Modes have the following impact on code performance and coverage:
- - performance: NORMAL > STRONG > OVERALL
- - coverage: NORMAL < STRONG < OVERALL
-
-
-config STACK_CHECK_NONE
- bool "None"
-config STACK_CHECK_NORM
- bool "Normal"
-config STACK_CHECK_STRONG
- bool "Strong"
-config STACK_CHECK_ALL
- bool "Overall"
-endchoice
-
-config STACK_CHECK
- bool
- default !STACK_CHECK_NONE
- help
- Stack smashing protection.
-
-config WARN_WRITE_STRINGS
- bool "Enable -Wwrite-strings warning flag"
- default "n"
- help
- Adds -Wwrite-strings flag for the C/C++ compilers.
-
- For C, this gives string constants the type "const char[]" so that
- copying the address of one into a non-"const" "char *" pointer
- produces a warning. This warning helps to find at compile time code
- that tries to write into a string constant.
-
- For C++, this warns about the deprecated conversion from string
- literals to "char *".
-
-endmenu # Compiler Options
+source "$IDF_PATH/Kconfig.compiler"
menu "Component config"
source "$COMPONENT_KCONFIGS"
diff --git a/Kconfig.compiler b/Kconfig.compiler
new file mode 100644
index 0000000000..ab689e88f2
--- /dev/null
+++ b/Kconfig.compiler
@@ -0,0 +1,135 @@
+menu "Compiler options"
+
+choice OPTIMIZATION_COMPILER
+ prompt "Optimization Level"
+ default OPTIMIZATION_LEVEL_DEBUG
+ help
+ This option sets compiler optimization level (gcc -O argument).
+
+ - for "Release" setting, -Os flag is added to CFLAGS.
+ - for "Debug" setting, -Og flag is added to CFLAGS.
+
+ "Release" with -Os produces smaller & faster compiled code but it
+ may be harder to correlated code addresses to source files when debugging.
+
+ To add custom optimization settings, set CFLAGS and/or CPPFLAGS
+ in project makefile, before including $(IDF_PATH)/make/project.mk. Note that
+ custom optimization levels may be unsupported.
+
+config OPTIMIZATION_LEVEL_DEBUG
+ bool "Debug (-Og)"
+config OPTIMIZATION_LEVEL_RELEASE
+ bool "Release (-Os)"
+endchoice
+
+choice OPTIMIZATION_ASSERTION_LEVEL
+ prompt "Assertion level"
+ default OPTIMIZATION_ASSERTIONS_ENABLED
+ help
+ Assertions can be:
+
+ - Enabled. Failure will print verbose assertion details. This is the default.
+
+ - Set to "silent" to save code size (failed assertions will abort() but user
+ needs to use the aborting address to find the line number with the failed assertion.)
+
+ - Disabled entirely (not recommended for most configurations.) -DNDEBUG is added
+ to CPPFLAGS in this case.
+
+config OPTIMIZATION_ASSERTIONS_ENABLED
+ prompt "Enabled"
+ bool
+ help
+ Enable assertions. Assertion content and line number will be printed on failure.
+
+config OPTIMIZATION_ASSERTIONS_SILENT
+ prompt "Silent (saves code size)"
+ bool
+ help
+ Enable silent assertions. Failed assertions will abort(), user needs to
+ use the aborting address to find the line number with the failed assertion.
+
+config OPTIMIZATION_ASSERTIONS_DISABLED
+ prompt "Disabled (sets -DNDEBUG)"
+ bool
+ help
+ If assertions are disabled, -DNDEBUG is added to CPPFLAGS.
+
+endchoice # assertions
+
+menuconfig CXX_EXCEPTIONS
+ bool "Enable C++ exceptions"
+ default n
+ help
+ Enabling this option compiles all IDF C++ files with exception support enabled.
+
+ Disabling this option disables C++ exception support in all compiled files, and any libstdc++ code which throws
+ an exception will abort instead.
+
+ Enabling this option currently adds an additional ~500 bytes of heap overhead
+ when an exception is thrown in user code for the first time.
+
+config CXX_EXCEPTIONS_EMG_POOL_SIZE
+ int "Emergency Pool Size"
+ default 0
+ depends on CXX_EXCEPTIONS
+ help
+ Size (in bytes) of the emergency memory pool for C++ exceptions. This pool will be used to allocate
+ memory for thrown exceptions when there is not enough memory on the heap.
+
+choice STACK_CHECK_MODE
+ prompt "Stack smashing protection mode"
+ default STACK_CHECK_NONE
+ help
+ Stack smashing protection mode. Emit extra code to check for buffer overflows, such as stack
+ smashing attacks. This is done by adding a guard variable to functions with vulnerable objects.
+ The guards are initialized when a function is entered and then checked when the function exits.
+ If a guard check fails, program is halted. Protection has the following modes:
+
+ - In NORMAL mode (GCC flag: -fstack-protector) only functions that call alloca,
+ and functions with buffers larger than 8 bytes are protected.
+
+ - STRONG mode (GCC flag: -fstack-protector-strong) is like NORMAL, but includes
+ additional functions to be protected -- those that have local array definitions,
+ or have references to local frame addresses.
+
+ - In OVERALL mode (GCC flag: -fstack-protector-all) all functions are protected.
+
+ Modes have the following impact on code performance and coverage:
+
+ - performance: NORMAL > STRONG > OVERALL
+
+ - coverage: NORMAL < STRONG < OVERALL
+
+
+config STACK_CHECK_NONE
+ bool "None"
+config STACK_CHECK_NORM
+ bool "Normal"
+config STACK_CHECK_STRONG
+ bool "Strong"
+config STACK_CHECK_ALL
+ bool "Overall"
+endchoice
+
+config STACK_CHECK
+ bool
+ default !STACK_CHECK_NONE
+ help
+ Stack smashing protection.
+
+config WARN_WRITE_STRINGS
+ bool "Enable -Wwrite-strings warning flag"
+ default "n"
+ help
+ Adds -Wwrite-strings flag for the C/C++ compilers.
+
+ For C, this gives string constants the type ``const char[]`` so that
+ copying the address of one into a non-const ``char *`` pointer
+ produces a warning. This warning helps to find at compile time code
+ that tries to write into a string constant.
+
+ For C++, this warns about the deprecated conversion from string
+ literals to ``char *``.
+
+endmenu # Compiler Options
diff --git a/README.md b/README.md
index 631d54a407..dadcdfb61e 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,33 @@
# Espressif IoT Development Framework
-[](https://esp-idf.readthedocs.io/en/latest/?badge=latest)
+[](https://docs.espressif.com/projects/esp-idf/en/latest/?badge=latest)
ESP-IDF is the official development framework for the [ESP32](https://espressif.com/en/products/hardware/esp32/overview) chip.
-# Developing With the ESP-IDF
+# Developing With ESP-IDF
## Setting Up ESP-IDF
See setup guides for detailed instructions to set up the ESP-IDF:
-* [Windows Setup Guide](https://esp-idf.readthedocs.io/en/latest/get-started/windows-setup.html)
-* [Mac OS Setup Guide](https://esp-idf.readthedocs.io/en/latest/get-started/macos-setup.html)
-* [Linux Setup Guide](https://esp-idf.readthedocs.io/en/latest/get-started/linux-setup.html)
+* [Getting Started Guide for the stable ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/)
+* [Getting Started Guide for the latest (master branch) ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/)
## Finding a Project
-As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in the setup guide, ESP-IDF comes with some example projects in the [examples](examples) directory.
+As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in Getting Started, ESP-IDF comes with some example projects in the [examples](examples) directory.
Once you've found the project you want to work with, change to its directory and you can configure and build it.
+To start your own project based on an example, copy the example project directory outside of the ESP-IDF directory.
+
+# Quick Reference
+
+See the Getting Started guide links above for a detailed setup guide. This is a quick reference for common commands when working with ESP-IDF projects:
+
## Configuring the Project
-`idf.py menuconfig`
+`make menuconfig`
* Opens a text-based configuration menu for the project.
* Use up & down arrow keys to navigate the menu.
@@ -36,41 +41,54 @@ Once done configuring, press Escape multiple times to exit and say "Yes" to save
## Compiling the Project
-`idf.py build`
+`make -j4 all`
... will compile app, bootloader and generate a partition table based on the config.
+NOTE: The `-j4` option causes `make` to run 4 parallel jobs. This is much faster than the default single job. The recommended number to pass to this option is `-j(number of CPUs + 1)`.
+
## Flashing the Project
When the build finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this automatically by running:
-`idf.py flash`
+`make -j4 flash`
-This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `idf.py menuconfig`.
+This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `make menuconfig`.
-You don't need to run `idf.py build` before running `idf.py flash`, `idf.py flash` will automatically rebuild anything which needs it.
+You don't need to run `make all` before running `make flash`, `make flash` will automatically rebuild anything which needs it.
## Viewing Serial Output
-The `idf.py monitor` target uses the [idf_monitor tool](https://esp-idf.readthedocs.io/en/latest/get-started/idf-monitor.html) to display serial output from the ESP32. idf_monitor also has a range of features to decode crash output and interact with the device. [Check the documentation page for details](https://esp-idf.readthedocs.io/en/latest/get-started/idf-monitor.html).
+The `make monitor` target uses the [idf_monitor tool](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html) to display serial output from the ESP32. idf_monitor also has a range of features to decode crash output and interact with the device. [Check the documentation page for details](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html).
Exit the monitor by typing Ctrl-].
-To flash and monitor output in one pass, you can run:
+To build, flash and monitor output in one pass, you can run:
-`idf.py flash monitor`
+`make -j4 flash monitor`
-## Compiling & Flashing Just the App
+## Compiling & Flashing Only the App
After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table:
-* `idf.py app` - build just the app.
-* `idf.py app-flash` - flash just the app.
+* `make app` - build just the app.
+* `make app-flash` - flash just the app.
-`idf.py app-flash` will automatically rebuild the app if it needs it.
+`make app-flash` will automatically rebuild the app if any source files have changed.
(In normal development there's no downside to reflashing the bootloader and partition table each time, if they haven't changed.)
+## Parallel Builds
+
+ESP-IDF supports compiling multiple files in parallel, so all of the above commands can be run as `make -jN` where `N` is the number of parallel make processes to run (generally N should be equal to the number of CPU cores in your system, plus one.)
+
+Multiple make functions can be combined into one. For example: to build the app & bootloader using 5 jobs in parallel, then flash everything, and then display serial output from the ESP32 run:
+
+```
+make -j5 flash monitor
+```
+
+
## The Partition Table
Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader.
@@ -79,29 +97,29 @@ A single ESP32's flash can contain multiple apps, as well as many different kind
Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded.
-The simplest way to use the partition table is to `idf.py menuconfig` and choose one of the simple predefined partition tables:
+The simplest way to use the partition table is to `make menuconfig` and choose one of the simple predefined partition tables:
* "Single factory app, no OTA"
* "Factory app, two OTA definitions"
-In both cases the factory app is flashed at offset 0x10000. If you `idf.py partition_table` then it will print a summary of the partition table.
+In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table.
For more details about partition tables and how to create custom variations, view the [`docs/en/api-guides/partition-tables.rst`](docs/en/api-guides/partition-tables.rst) file.
## Erasing Flash
-The `idf.py flash` target does not erase the entire flash contents. However it is sometimes useful to set the device back to a totally erased state, particularly when making partition table changes or OTA app updates. To erase the entire flash, run `idf.py erase_flash`.
+The `make flash` target does not erase the entire flash contents. However it is sometimes useful to set the device back to a totally erased state, particularly when making partition table changes or OTA app updates. To erase the entire flash, run `make erase_flash`.
-This can be combined with other targets, ie `idf.py erase_flash flash` will erase everything and then re-flash the new app, bootloader and partition table.
+This can be combined with other targets, ie `make erase_flash flash` will erase everything and then re-flash the new app, bootloader and partition table.
# Resources
-* Documentation for the latest version: https://esp-idf.readthedocs.io/. This documentation is built from the [docs directory](docs) of this repository.
+* Documentation for the latest version: https://docs.espressif.com/projects/esp-idf/. This documentation is built from the [docs directory](docs) of this repository.
* The [esp32.com forum](https://esp32.com/) is a place to ask questions and find community resources.
* [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one.
-* If you're interested in contributing to ESP-IDF, please check the [Contributions Guide](https://esp-idf.readthedocs.io/en/latest/contribute/index.html).
+* If you're interested in contributing to ESP-IDF, please check the [Contributions Guide](https://docs.espressif.com/projects/esp-idf/en/latest/contribute/index.html).
diff --git a/components/app_trace/Kconfig b/components/app_trace/Kconfig
index d80331996b..d599efe85a 100644
--- a/components/app_trace/Kconfig
+++ b/components/app_trace/Kconfig
@@ -56,6 +56,7 @@ config ESP32_APPTRACE_PENDING_DATA_SIZE_MAX
events will be discarded when main HW buffer is full.
menu "FreeRTOS SystemView Tracing"
+ depends on ESP32_APPTRACE_ENABLE
config SYSVIEW_ENABLE
bool "SystemView Tracing Enable"
depends on ESP32_APPTRACE_ENABLE
diff --git a/components/app_trace/host_file_io.c b/components/app_trace/host_file_io.c
index a6dd35c08c..b818440145 100644
--- a/components/app_trace/host_file_io.c
+++ b/components/app_trace/host_file_io.c
@@ -279,6 +279,8 @@ static void esp_apptrace_fseek_args_prepare(uint8_t *buf, void *priv)
esp_apptrace_fseek_args_t *args = priv;
memcpy(buf, &args->file, sizeof(args->file));
+ memcpy(buf + sizeof(args->file), &args->offset, sizeof(args->offset));
+ memcpy(buf + sizeof(args->file) + sizeof(args->offset), &args->whence, sizeof(args->whence));
}
int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int whence)
diff --git a/components/app_trace/sys_view/Config/Global.h b/components/app_trace/sys_view/Config/Global.h
index 6ba942b7e5..bd767ee085 100644
--- a/components/app_trace/sys_view/Config/Global.h
+++ b/components/app_trace/sys_view/Config/Global.h
@@ -1,102 +1,102 @@
-/*********************************************************************
-* SEGGER Microcontroller GmbH & Co. KG *
-* The Embedded Experts *
-**********************************************************************
-* *
-* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
-* *
-* www.segger.com Support: support@segger.com *
-* *
-**********************************************************************
-* *
-* SEGGER SystemView * Real-time application analysis *
-* *
-**********************************************************************
-* *
-* All rights reserved. *
-* *
-* SEGGER strongly recommends to not make any changes *
-* to or modify the source code of this software in order to stay *
-* compatible with the RTT protocol and J-Link. *
-* *
-* Redistribution and use in source and binary forms, with or *
-* without modification, are permitted provided that the following *
-* conditions are met: *
-* *
-* o Redistributions of source code must retain the above copyright *
-* notice, this list of conditions and the following disclaimer. *
-* *
-* o Redistributions in binary form must reproduce the above *
-* copyright notice, this list of conditions and the following *
-* disclaimer in the documentation and/or other materials provided *
-* with the distribution. *
-* *
-* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
-* nor the names of its contributors may be used to endorse or *
-* promote products derived from this software without specific *
-* prior written permission. *
-* *
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
-* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
-* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
-* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
-* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
-* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
-* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
-* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
-* DAMAGE. *
-* *
-**********************************************************************
-* *
-* SystemView version: V2.42 *
-* *
-**********************************************************************
-----------------------------------------------------------------------
-File : Global.h
-Purpose : Global types
- In case your application already has a Global.h, you should
- merge the files. In order to use Segger code, the types
- U8, U16, U32, I8, I16, I32 need to be defined in Global.h;
- additional definitions do not hurt.
----------------------------END-OF-HEADER------------------------------
-*/
-
-#ifndef GLOBAL_H // Guard against multiple inclusion
-#define GLOBAL_H
-
-#define U8 unsigned char
-#define U16 unsigned short
-#define U32 unsigned long
-#define I8 signed char
-#define I16 signed short
-#define I32 signed long
-
-#ifdef _WIN32
- //
- // Microsoft VC6 compiler related
- //
- #define U64 unsigned __int64
- #define U128 unsigned __int128
- #define I64 __int64
- #define I128 __int128
- #if _MSC_VER <= 1200
- #define U64_C(x) x##UI64
- #else
- #define U64_C(x) x##ULL
- #endif
-#else
- //
- // C99 compliant compiler
- //
- #define U64 unsigned long long
- #define I64 signed long long
- #define U64_C(x) x##ULL
-#endif
-
-#endif // Avoid multiple inclusion
-
-/*************************** End of file ****************************/
+/*********************************************************************
+* SEGGER Microcontroller GmbH & Co. KG *
+* The Embedded Experts *
+**********************************************************************
+* *
+* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
+* *
+* www.segger.com Support: support@segger.com *
+* *
+**********************************************************************
+* *
+* SEGGER SystemView * Real-time application analysis *
+* *
+**********************************************************************
+* *
+* All rights reserved. *
+* *
+* SEGGER strongly recommends to not make any changes *
+* to or modify the source code of this software in order to stay *
+* compatible with the RTT protocol and J-Link. *
+* *
+* Redistribution and use in source and binary forms, with or *
+* without modification, are permitted provided that the following *
+* conditions are met: *
+* *
+* o Redistributions of source code must retain the above copyright *
+* notice, this list of conditions and the following disclaimer. *
+* *
+* o Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the following *
+* disclaimer in the documentation and/or other materials provided *
+* with the distribution. *
+* *
+* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
+* nor the names of its contributors may be used to endorse or *
+* promote products derived from this software without specific *
+* prior written permission. *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
+* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
+* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
+* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
+* DAMAGE. *
+* *
+**********************************************************************
+* *
+* SystemView version: V2.42 *
+* *
+**********************************************************************
+----------------------------------------------------------------------
+File : Global.h
+Purpose : Global types
+ In case your application already has a Global.h, you should
+ merge the files. In order to use Segger code, the types
+ U8, U16, U32, I8, I16, I32 need to be defined in Global.h;
+ additional definitions do not hurt.
+---------------------------END-OF-HEADER------------------------------
+*/
+
+#ifndef GLOBAL_H // Guard against multiple inclusion
+#define GLOBAL_H
+
+#define U8 unsigned char
+#define U16 unsigned short
+#define U32 unsigned long
+#define I8 signed char
+#define I16 signed short
+#define I32 signed long
+
+#ifdef _WIN32
+ //
+ // Microsoft VC6 compiler related
+ //
+ #define U64 unsigned __int64
+ #define U128 unsigned __int128
+ #define I64 __int64
+ #define I128 __int128
+ #if _MSC_VER <= 1200
+ #define U64_C(x) x##UI64
+ #else
+ #define U64_C(x) x##ULL
+ #endif
+#else
+ //
+ // C99 compliant compiler
+ //
+ #define U64 unsigned long long
+ #define I64 signed long long
+ #define U64_C(x) x##ULL
+#endif
+
+#endif // Avoid multiple inclusion
+
+/*************************** End of file ****************************/
diff --git a/components/app_trace/sys_view/Config/SEGGER_RTT_Conf.h b/components/app_trace/sys_view/Config/SEGGER_RTT_Conf.h
index 49944e739b..2325944e5a 100644
--- a/components/app_trace/sys_view/Config/SEGGER_RTT_Conf.h
+++ b/components/app_trace/sys_view/Config/SEGGER_RTT_Conf.h
@@ -1,298 +1,298 @@
-/*********************************************************************
-* SEGGER Microcontroller GmbH & Co. KG *
-* The Embedded Experts *
-**********************************************************************
-* *
-* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
-* *
-* www.segger.com Support: support@segger.com *
-* *
-**********************************************************************
-* *
-* SEGGER SystemView * Real-time application analysis *
-* *
-**********************************************************************
-* *
-* All rights reserved. *
-* *
-* SEGGER strongly recommends to not make any changes *
-* to or modify the source code of this software in order to stay *
-* compatible with the RTT protocol and J-Link. *
-* *
-* Redistribution and use in source and binary forms, with or *
-* without modification, are permitted provided that the following *
-* conditions are met: *
-* *
-* o Redistributions of source code must retain the above copyright *
-* notice, this list of conditions and the following disclaimer. *
-* *
-* o Redistributions in binary form must reproduce the above *
-* copyright notice, this list of conditions and the following *
-* disclaimer in the documentation and/or other materials provided *
-* with the distribution. *
-* *
-* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
-* nor the names of its contributors may be used to endorse or *
-* promote products derived from this software without specific *
-* prior written permission. *
-* *
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
-* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
-* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
-* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
-* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
-* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
-* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
-* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
-* DAMAGE. *
-* *
-**********************************************************************
-* *
-* SystemView version: V2.42 *
-* *
-**********************************************************************
----------------------------END-OF-HEADER------------------------------
-File : SEGGER_RTT_Conf.h
-Purpose : Implementation of SEGGER real-time transfer (RTT) which
- allows real-time communication on targets which support
- debugger memory accesses while the CPU is running.
-Revision: $Rev: 5626 $
-
-*/
-
-#ifndef SEGGER_RTT_CONF_H
-#define SEGGER_RTT_CONF_H
-
-#ifdef __IAR_SYSTEMS_ICC__
- #include
-#endif
-
-/*********************************************************************
-*
-* Defines, configurable
-*
-**********************************************************************
-*/
-
-#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3)
-#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3)
-
-#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k)
-#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
-
-#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
-
-#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
-
-//
-// Target is not allowed to perform other RTT operations while string still has not been stored completely.
-// Otherwise we would probably end up with a mixed string in the buffer.
-// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
-//
-// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
-// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
-// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
-// (Higher priority = lower priority number)
-// Default value for embOS: 128u
-// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
-// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
-// or define SEGGER_RTT_LOCK() to completely disable interrupts.
-//
-
-#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
-
-/*********************************************************************
-*
-* RTT lock configuration for SEGGER Embedded Studio,
-* Rowley CrossStudio and GCC
-*/
-#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
- #ifdef __ARM_ARCH_6M__
- #define SEGGER_RTT_LOCK() { \
- unsigned int LockState; \
- __asm volatile ("mrs %0, primask \n\t" \
- "mov r1, $1 \n\t" \
- "msr primask, r1 \n\t" \
- : "=r" (LockState) \
- : \
- : "r1" \
- );
-
- #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
- : \
- : "r" (LockState) \
- : \
- ); \
- }
-
- #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
- #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
- #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
- #endif
- #define SEGGER_RTT_LOCK() { \
- unsigned int LockState; \
- __asm volatile ("mrs %0, basepri \n\t" \
- "mov r1, %1 \n\t" \
- "msr basepri, r1 \n\t" \
- : "=r" (LockState) \
- : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
- : "r1" \
- );
-
- #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
- : \
- : "r" (LockState) \
- : \
- ); \
- }
-
- #elif defined(__ARM_ARCH_7A__)
- #define SEGGER_RTT_LOCK() { \
- unsigned int LockState; \
- __asm volatile ("mrs r1, CPSR \n\t" \
- "mov %0, r1 \n\t" \
- "orr r1, r1, #0xC0 \n\t" \
- "msr CPSR_c, r1 \n\t" \
- : "=r" (LockState) \
- : \
- : "r1" \
- );
-
- #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
- "mrs r1, CPSR \n\t" \
- "bic r1, r1, #0xC0 \n\t" \
- "and r0, r0, #0xC0 \n\t" \
- "orr r1, r1, r0 \n\t" \
- "msr CPSR_c, r1 \n\t" \
- : \
- : "r" (LockState) \
- : "r0", "r1" \
- ); \
- }
-#else
- #define SEGGER_RTT_LOCK()
- #define SEGGER_RTT_UNLOCK()
- #endif
-#endif
-
-/*********************************************************************
-*
-* RTT lock configuration for IAR EWARM
-*/
-#ifdef __ICCARM__
- #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
- #define SEGGER_RTT_LOCK() { \
- unsigned int LockState; \
- LockState = __get_PRIMASK(); \
- __set_PRIMASK(1);
-
- #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
- }
- #elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__)))
- #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
- #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
- #endif
- #define SEGGER_RTT_LOCK() { \
- unsigned int LockState; \
- LockState = __get_BASEPRI(); \
- __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
-
- #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \
- }
- #endif
-#endif
-
-/*********************************************************************
-*
-* RTT lock configuration for IAR RX
-*/
-#ifdef __ICCRX__
- #define SEGGER_RTT_LOCK() { \
- unsigned long LockState; \
- LockState = __get_interrupt_state(); \
- __disable_interrupt();
-
- #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
- }
-#endif
-
-/*********************************************************************
-*
-* RTT lock configuration for KEIL ARM
-*/
-#ifdef __CC_ARM
- #if (defined __TARGET_ARCH_6S_M)
- #define SEGGER_RTT_LOCK() { \
- unsigned int LockState; \
- register unsigned char PRIMASK __asm( "primask"); \
- LockState = PRIMASK; \
- PRIMASK = 1u; \
- __schedule_barrier();
-
- #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \
- __schedule_barrier(); \
- }
- #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
- #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
- #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
- #endif
- #define SEGGER_RTT_LOCK() { \
- unsigned int LockState; \
- register unsigned char BASEPRI __asm( "basepri"); \
- LockState = BASEPRI; \
- BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
- __schedule_barrier();
-
- #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \
- __schedule_barrier(); \
- }
- #endif
-#endif
-
-/*********************************************************************
-*
-* RTT lock configuration for TI ARM
-*/
-#ifdef __TI_ARM__
- #if defined (__TI_ARM_V6M0__)
- #define SEGGER_RTT_LOCK() { \
- unsigned int LockState; \
- LockState = __get_PRIMASK(); \
- __set_PRIMASK(1);
-
- #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
- }
- #elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
- #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
- #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
- #endif
- #define SEGGER_RTT_LOCK() { \
- unsigned int LockState; \
- LockState = OS_GetBASEPRI(); \
- OS_SetBASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
-
- #define SEGGER_RTT_UNLOCK() OS_SetBASEPRI(LockState); \
- }
- #endif
-#endif
-
-/*********************************************************************
-*
-* RTT lock configuration fallback
-*/
-#ifndef SEGGER_RTT_LOCK
- void SEGGER_SYSVIEW_X_RTT_Lock();
- #define SEGGER_RTT_LOCK() SEGGER_SYSVIEW_X_RTT_Lock() // Lock RTT (nestable) (i.e. disable interrupts)
-#endif
-
-#ifndef SEGGER_RTT_UNLOCK
- void SEGGER_SYSVIEW_X_RTT_Unlock();
- #define SEGGER_RTT_UNLOCK() SEGGER_SYSVIEW_X_RTT_Unlock() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
-#endif
-
-#endif
-/*************************** End of file ****************************/
+/*********************************************************************
+* SEGGER Microcontroller GmbH & Co. KG *
+* The Embedded Experts *
+**********************************************************************
+* *
+* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
+* *
+* www.segger.com Support: support@segger.com *
+* *
+**********************************************************************
+* *
+* SEGGER SystemView * Real-time application analysis *
+* *
+**********************************************************************
+* *
+* All rights reserved. *
+* *
+* SEGGER strongly recommends to not make any changes *
+* to or modify the source code of this software in order to stay *
+* compatible with the RTT protocol and J-Link. *
+* *
+* Redistribution and use in source and binary forms, with or *
+* without modification, are permitted provided that the following *
+* conditions are met: *
+* *
+* o Redistributions of source code must retain the above copyright *
+* notice, this list of conditions and the following disclaimer. *
+* *
+* o Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the following *
+* disclaimer in the documentation and/or other materials provided *
+* with the distribution. *
+* *
+* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
+* nor the names of its contributors may be used to endorse or *
+* promote products derived from this software without specific *
+* prior written permission. *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
+* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
+* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
+* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
+* DAMAGE. *
+* *
+**********************************************************************
+* *
+* SystemView version: V2.42 *
+* *
+**********************************************************************
+---------------------------END-OF-HEADER------------------------------
+File : SEGGER_RTT_Conf.h
+Purpose : Implementation of SEGGER real-time transfer (RTT) which
+ allows real-time communication on targets which support
+ debugger memory accesses while the CPU is running.
+Revision: $Rev: 5626 $
+
+*/
+
+#ifndef SEGGER_RTT_CONF_H
+#define SEGGER_RTT_CONF_H
+
+#ifdef __IAR_SYSTEMS_ICC__
+ #include
+#endif
+
+/*********************************************************************
+*
+* Defines, configurable
+*
+**********************************************************************
+*/
+
+#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3)
+#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3)
+
+#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k)
+#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
+
+#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
+
+#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
+
+//
+// Target is not allowed to perform other RTT operations while string still has not been stored completely.
+// Otherwise we would probably end up with a mixed string in the buffer.
+// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
+//
+// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
+// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
+// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
+// (Higher priority = lower priority number)
+// Default value for embOS: 128u
+// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
+// or define SEGGER_RTT_LOCK() to completely disable interrupts.
+//
+
+#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
+
+/*********************************************************************
+*
+* RTT lock configuration for SEGGER Embedded Studio,
+* Rowley CrossStudio and GCC
+*/
+#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
+ #ifdef __ARM_ARCH_6M__
+ #define SEGGER_RTT_LOCK() { \
+ unsigned int LockState; \
+ __asm volatile ("mrs %0, primask \n\t" \
+ "mov r1, $1 \n\t" \
+ "msr primask, r1 \n\t" \
+ : "=r" (LockState) \
+ : \
+ : "r1" \
+ );
+
+ #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
+ : \
+ : "r" (LockState) \
+ : \
+ ); \
+ }
+
+ #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
+ #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
+ #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
+ #endif
+ #define SEGGER_RTT_LOCK() { \
+ unsigned int LockState; \
+ __asm volatile ("mrs %0, basepri \n\t" \
+ "mov r1, %1 \n\t" \
+ "msr basepri, r1 \n\t" \
+ : "=r" (LockState) \
+ : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
+ : "r1" \
+ );
+
+ #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
+ : \
+ : "r" (LockState) \
+ : \
+ ); \
+ }
+
+ #elif defined(__ARM_ARCH_7A__)
+ #define SEGGER_RTT_LOCK() { \
+ unsigned int LockState; \
+ __asm volatile ("mrs r1, CPSR \n\t" \
+ "mov %0, r1 \n\t" \
+ "orr r1, r1, #0xC0 \n\t" \
+ "msr CPSR_c, r1 \n\t" \
+ : "=r" (LockState) \
+ : \
+ : "r1" \
+ );
+
+ #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
+ "mrs r1, CPSR \n\t" \
+ "bic r1, r1, #0xC0 \n\t" \
+ "and r0, r0, #0xC0 \n\t" \
+ "orr r1, r1, r0 \n\t" \
+ "msr CPSR_c, r1 \n\t" \
+ : \
+ : "r" (LockState) \
+ : "r0", "r1" \
+ ); \
+ }
+#else
+ #define SEGGER_RTT_LOCK()
+ #define SEGGER_RTT_UNLOCK()
+ #endif
+#endif
+
+/*********************************************************************
+*
+* RTT lock configuration for IAR EWARM
+*/
+#ifdef __ICCARM__
+ #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
+ #define SEGGER_RTT_LOCK() { \
+ unsigned int LockState; \
+ LockState = __get_PRIMASK(); \
+ __set_PRIMASK(1);
+
+ #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
+ }
+ #elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__)))
+ #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
+ #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
+ #endif
+ #define SEGGER_RTT_LOCK() { \
+ unsigned int LockState; \
+ LockState = __get_BASEPRI(); \
+ __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
+
+ #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \
+ }
+ #endif
+#endif
+
+/*********************************************************************
+*
+* RTT lock configuration for IAR RX
+*/
+#ifdef __ICCRX__
+ #define SEGGER_RTT_LOCK() { \
+ unsigned long LockState; \
+ LockState = __get_interrupt_state(); \
+ __disable_interrupt();
+
+ #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
+ }
+#endif
+
+/*********************************************************************
+*
+* RTT lock configuration for KEIL ARM
+*/
+#ifdef __CC_ARM
+ #if (defined __TARGET_ARCH_6S_M)
+ #define SEGGER_RTT_LOCK() { \
+ unsigned int LockState; \
+ register unsigned char PRIMASK __asm( "primask"); \
+ LockState = PRIMASK; \
+ PRIMASK = 1u; \
+ __schedule_barrier();
+
+ #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \
+ __schedule_barrier(); \
+ }
+ #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
+ #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
+ #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
+ #endif
+ #define SEGGER_RTT_LOCK() { \
+ unsigned int LockState; \
+ register unsigned char BASEPRI __asm( "basepri"); \
+ LockState = BASEPRI; \
+ BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
+ __schedule_barrier();
+
+ #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \
+ __schedule_barrier(); \
+ }
+ #endif
+#endif
+
+/*********************************************************************
+*
+* RTT lock configuration for TI ARM
+*/
+#ifdef __TI_ARM__
+ #if defined (__TI_ARM_V6M0__)
+ #define SEGGER_RTT_LOCK() { \
+ unsigned int LockState; \
+ LockState = __get_PRIMASK(); \
+ __set_PRIMASK(1);
+
+ #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
+ }
+ #elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
+ #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
+ #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
+ #endif
+ #define SEGGER_RTT_LOCK() { \
+ unsigned int LockState; \
+ LockState = OS_GetBASEPRI(); \
+ OS_SetBASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
+
+ #define SEGGER_RTT_UNLOCK() OS_SetBASEPRI(LockState); \
+ }
+ #endif
+#endif
+
+/*********************************************************************
+*
+* RTT lock configuration fallback
+*/
+#ifndef SEGGER_RTT_LOCK
+ void SEGGER_SYSVIEW_X_RTT_Lock();
+ #define SEGGER_RTT_LOCK() SEGGER_SYSVIEW_X_RTT_Lock() // Lock RTT (nestable) (i.e. disable interrupts)
+#endif
+
+#ifndef SEGGER_RTT_UNLOCK
+ void SEGGER_SYSVIEW_X_RTT_Unlock();
+ #define SEGGER_RTT_UNLOCK() SEGGER_SYSVIEW_X_RTT_Unlock() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
+#endif
+
+#endif
+/*************************** End of file ****************************/
diff --git a/components/app_trace/sys_view/Config/SEGGER_SYSVIEW_Conf.h b/components/app_trace/sys_view/Config/SEGGER_SYSVIEW_Conf.h
index f6c5f09375..787237a00b 100644
--- a/components/app_trace/sys_view/Config/SEGGER_SYSVIEW_Conf.h
+++ b/components/app_trace/sys_view/Config/SEGGER_SYSVIEW_Conf.h
@@ -1,176 +1,176 @@
-/*********************************************************************
-* SEGGER Microcontroller GmbH & Co. KG *
-* The Embedded Experts *
-**********************************************************************
-* *
-* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
-* *
-* www.segger.com Support: support@segger.com *
-* *
-**********************************************************************
-* *
-* SEGGER SystemView * Real-time application analysis *
-* *
-**********************************************************************
-* *
-* All rights reserved. *
-* *
-* SEGGER strongly recommends to not make any changes *
-* to or modify the source code of this software in order to stay *
-* compatible with the RTT protocol and J-Link. *
-* *
-* Redistribution and use in source and binary forms, with or *
-* without modification, are permitted provided that the following *
-* conditions are met: *
-* *
-* o Redistributions of source code must retain the above copyright *
-* notice, this list of conditions and the following disclaimer. *
-* *
-* o Redistributions in binary form must reproduce the above *
-* copyright notice, this list of conditions and the following *
-* disclaimer in the documentation and/or other materials provided *
-* with the distribution. *
-* *
-* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
-* nor the names of its contributors may be used to endorse or *
-* promote products derived from this software without specific *
-* prior written permission. *
-* *
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
-* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
-* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
-* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
-* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
-* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
-* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
-* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
-* DAMAGE. *
-* *
-**********************************************************************
-* *
-* SystemView version: V2.42 *
-* *
-**********************************************************************
--------------------------- END-OF-HEADER -----------------------------
-
-File : SEGGER_SYSVIEW_Conf.h
-Purpose : SEGGER SystemView configuration.
-Revision: $Rev: 5927 $
-*/
-
-#ifndef SEGGER_SYSVIEW_CONF_H
-#define SEGGER_SYSVIEW_CONF_H
-
-/*********************************************************************
-*
-* Defines, fixed
-*
-**********************************************************************
-*/
-//
-// Constants for known core configuration
-//
-#define SEGGER_SYSVIEW_CORE_OTHER 0
-#define SEGGER_SYSVIEW_CORE_CM0 1 // Cortex-M0/M0+/M1
-#define SEGGER_SYSVIEW_CORE_CM3 2 // Cortex-M3/M4/M7
-#define SEGGER_SYSVIEW_CORE_RX 3 // Renesas RX
-
-#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
- #ifdef __ARM_ARCH_6M__
- #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
- #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
- #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
- #endif
-#elif defined(__ICCARM__)
- #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
- #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
- #elif ((defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)))
- #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
- #endif
-#elif defined(__CC_ARM)
- #if (defined(__TARGET_ARCH_6S_M))
- #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
- #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
- #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
- #endif
-#elif defined(__TI_ARM__)
- #ifdef __TI_ARM_V6M0__
- #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
- #elif (defined(__TI_ARM_V7M3__) || defined(__TI_ARM_V7M4__))
- #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
- #endif
-#elif defined(__ICCRX__)
- #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
-#elif defined(__RX)
- #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
-#endif
-
-#ifndef SEGGER_SYSVIEW_CORE
- #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_OTHER
-#endif
-
-/*********************************************************************
-*
-* Defines, configurable
-*
-**********************************************************************
-*/
-/*********************************************************************
-*
-* SystemView buffer configuration
-*/
-#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024 // Number of bytes that SystemView uses for the buffer.
-#define SEGGER_SYSVIEW_RTT_CHANNEL 1 // The RTT channel that SystemView will use. 0: Auto selection
-
-#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1 // Use a static buffer to generate events instead of a buffer on the stack
-
-#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0 // 1: Enable post mortem analysis mode
-
-/*********************************************************************
-*
-* SystemView timestamp configuration
-*/
-#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
- #define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004)) // Retrieve a system timestamp. Cortex-M cycle counter.
- #define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by clock source
-#else
- #define SEGGER_SYSVIEW_GET_TIMESTAMP() SEGGER_SYSVIEW_X_GetTimestamp() // Retrieve a system timestamp via user-defined function
- #define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by SEGGER_SYSVIEW_X_GetTimestamp()
-#endif
-
-/*********************************************************************
-*
-* SystemView Id configuration
-*/
-//TODO: optimise it
-#define SEGGER_SYSVIEW_ID_BASE 0x3F400000 // Default value for the lowest Id reported by the application. Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase(). (i.e. 0x20000000 when all Ids are an address in this RAM)
-#define SEGGER_SYSVIEW_ID_SHIFT 0 // Number of bits to shift the Id to save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
-
-/*********************************************************************
-*
-* SystemView interrupt configuration
-*/
-#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
- #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x1FF) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[8:0] = active vector)
-#elif SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM0
- #if defined(__ICCARM__)
- #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() (__get_IPSR()) // Workaround for IAR, which might do a byte-access to 0xE000ED04. Read IPSR instead.
- #else
- #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x3F) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[5:0] = active vector)
- #endif
-#else
- #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() SEGGER_SYSVIEW_X_GetInterruptId() // Get the currently active interrupt Id from the user-provided function.
-#endif
-
-void SEGGER_SYSVIEW_X_SysView_Lock();
-void SEGGER_SYSVIEW_X_SysView_Unlock();
-#define SEGGER_SYSVIEW_LOCK() SEGGER_SYSVIEW_X_SysView_Lock()
-#define SEGGER_SYSVIEW_UNLOCK() SEGGER_SYSVIEW_X_SysView_Unlock()
-
-#endif // SEGGER_SYSVIEW_CONF_H
-
-/*************************** End of file ****************************/
+/*********************************************************************
+* SEGGER Microcontroller GmbH & Co. KG *
+* The Embedded Experts *
+**********************************************************************
+* *
+* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
+* *
+* www.segger.com Support: support@segger.com *
+* *
+**********************************************************************
+* *
+* SEGGER SystemView * Real-time application analysis *
+* *
+**********************************************************************
+* *
+* All rights reserved. *
+* *
+* SEGGER strongly recommends to not make any changes *
+* to or modify the source code of this software in order to stay *
+* compatible with the RTT protocol and J-Link. *
+* *
+* Redistribution and use in source and binary forms, with or *
+* without modification, are permitted provided that the following *
+* conditions are met: *
+* *
+* o Redistributions of source code must retain the above copyright *
+* notice, this list of conditions and the following disclaimer. *
+* *
+* o Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the following *
+* disclaimer in the documentation and/or other materials provided *
+* with the distribution. *
+* *
+* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
+* nor the names of its contributors may be used to endorse or *
+* promote products derived from this software without specific *
+* prior written permission. *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
+* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
+* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
+* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
+* DAMAGE. *
+* *
+**********************************************************************
+* *
+* SystemView version: V2.42 *
+* *
+**********************************************************************
+-------------------------- END-OF-HEADER -----------------------------
+
+File : SEGGER_SYSVIEW_Conf.h
+Purpose : SEGGER SystemView configuration.
+Revision: $Rev: 5927 $
+*/
+
+#ifndef SEGGER_SYSVIEW_CONF_H
+#define SEGGER_SYSVIEW_CONF_H
+
+/*********************************************************************
+*
+* Defines, fixed
+*
+**********************************************************************
+*/
+//
+// Constants for known core configuration
+//
+#define SEGGER_SYSVIEW_CORE_OTHER 0
+#define SEGGER_SYSVIEW_CORE_CM0 1 // Cortex-M0/M0+/M1
+#define SEGGER_SYSVIEW_CORE_CM3 2 // Cortex-M3/M4/M7
+#define SEGGER_SYSVIEW_CORE_RX 3 // Renesas RX
+
+#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
+ #ifdef __ARM_ARCH_6M__
+ #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
+ #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
+ #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
+ #endif
+#elif defined(__ICCARM__)
+ #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
+ #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
+ #elif ((defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)))
+ #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
+ #endif
+#elif defined(__CC_ARM)
+ #if (defined(__TARGET_ARCH_6S_M))
+ #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
+ #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
+ #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
+ #endif
+#elif defined(__TI_ARM__)
+ #ifdef __TI_ARM_V6M0__
+ #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
+ #elif (defined(__TI_ARM_V7M3__) || defined(__TI_ARM_V7M4__))
+ #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
+ #endif
+#elif defined(__ICCRX__)
+ #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
+#elif defined(__RX)
+ #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
+#endif
+
+#ifndef SEGGER_SYSVIEW_CORE
+ #define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_OTHER
+#endif
+
+/*********************************************************************
+*
+* Defines, configurable
+*
+**********************************************************************
+*/
+/*********************************************************************
+*
+* SystemView buffer configuration
+*/
+#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024 // Number of bytes that SystemView uses for the buffer.
+#define SEGGER_SYSVIEW_RTT_CHANNEL 1 // The RTT channel that SystemView will use. 0: Auto selection
+
+#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1 // Use a static buffer to generate events instead of a buffer on the stack
+
+#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0 // 1: Enable post mortem analysis mode
+
+/*********************************************************************
+*
+* SystemView timestamp configuration
+*/
+#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
+ #define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004)) // Retrieve a system timestamp. Cortex-M cycle counter.
+ #define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by clock source
+#else
+ #define SEGGER_SYSVIEW_GET_TIMESTAMP() SEGGER_SYSVIEW_X_GetTimestamp() // Retrieve a system timestamp via user-defined function
+ #define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by SEGGER_SYSVIEW_X_GetTimestamp()
+#endif
+
+/*********************************************************************
+*
+* SystemView Id configuration
+*/
+//TODO: optimise it
+#define SEGGER_SYSVIEW_ID_BASE 0x3F400000 // Default value for the lowest Id reported by the application. Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase(). (i.e. 0x20000000 when all Ids are an address in this RAM)
+#define SEGGER_SYSVIEW_ID_SHIFT 0 // Number of bits to shift the Id to save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
+
+/*********************************************************************
+*
+* SystemView interrupt configuration
+*/
+#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
+ #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x1FF) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[8:0] = active vector)
+#elif SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM0
+ #if defined(__ICCARM__)
+ #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() (__get_IPSR()) // Workaround for IAR, which might do a byte-access to 0xE000ED04. Read IPSR instead.
+ #else
+ #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x3F) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[5:0] = active vector)
+ #endif
+#else
+ #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() SEGGER_SYSVIEW_X_GetInterruptId() // Get the currently active interrupt Id from the user-provided function.
+#endif
+
+void SEGGER_SYSVIEW_X_SysView_Lock();
+void SEGGER_SYSVIEW_X_SysView_Unlock();
+#define SEGGER_SYSVIEW_LOCK() SEGGER_SYSVIEW_X_SysView_Lock()
+#define SEGGER_SYSVIEW_UNLOCK() SEGGER_SYSVIEW_X_SysView_Unlock()
+
+#endif // SEGGER_SYSVIEW_CONF_H
+
+/*************************** End of file ****************************/
diff --git a/components/app_trace/sys_view/SEGGER/SEGGER.h b/components/app_trace/sys_view/SEGGER/SEGGER.h
index 6b38e9cce3..c6e571cb72 100644
--- a/components/app_trace/sys_view/SEGGER/SEGGER.h
+++ b/components/app_trace/sys_view/SEGGER/SEGGER.h
@@ -1,155 +1,155 @@
-/*********************************************************************
-* SEGGER Microcontroller GmbH & Co. KG *
-* The Embedded Experts *
-**********************************************************************
-* *
-* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
-* *
-* www.segger.com Support: support@segger.com *
-* *
-**********************************************************************
-* *
-* SEGGER SystemView * Real-time application analysis *
-* *
-**********************************************************************
-* *
-* All rights reserved. *
-* *
-* SEGGER strongly recommends to not make any changes *
-* to or modify the source code of this software in order to stay *
-* compatible with the RTT protocol and J-Link. *
-* *
-* Redistribution and use in source and binary forms, with or *
-* without modification, are permitted provided that the following *
-* conditions are met: *
-* *
-* o Redistributions of source code must retain the above copyright *
-* notice, this list of conditions and the following disclaimer. *
-* *
-* o Redistributions in binary form must reproduce the above *
-* copyright notice, this list of conditions and the following *
-* disclaimer in the documentation and/or other materials provided *
-* with the distribution. *
-* *
-* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
-* nor the names of its contributors may be used to endorse or *
-* promote products derived from this software without specific *
-* prior written permission. *
-* *
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
-* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
-* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
-* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
-* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
-* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
-* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
-* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
-* DAMAGE. *
-* *
-**********************************************************************
-* *
-* SystemView version: V2.42 *
-* *
-**********************************************************************
-----------------------------------------------------------------------
-File : SEGGER.h
-Purpose : Global types etc & general purpose utility functions
----------------------------END-OF-HEADER------------------------------
-*/
-
-#ifndef SEGGER_H // Guard against multiple inclusion
-#define SEGGER_H
-
-#include "Global.h" // Type definitions: U8, U16, U32, I8, I16, I32
-
-#if defined(__cplusplus)
-extern "C" { /* Make sure we have C-declarations in C++ programs */
-#endif
-
-/*********************************************************************
-*
-* Keywords/specifiers
-*
-**********************************************************************
-*/
-
-#ifndef INLINE
- #ifdef _WIN32
- //
- // Microsoft VC6 and newer.
- // Force inlining without cost checking.
- //
- #define INLINE __forceinline
- #else
- #if (defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) || defined(__RX) || defined(__ICCRX__))
- //
- // Other known compilers.
- //
- #define INLINE inline
- #else
- //
- // Unknown compilers.
- //
- #define INLINE
- #endif
- #endif
-#endif
-
-/*********************************************************************
-*
-* Function-like macros
-*
-**********************************************************************
-*/
-
-#define SEGGER_COUNTOF(a) (sizeof((a))/sizeof((a)[0]))
-#define SEGGER_MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define SEGGER_MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-/*********************************************************************
-*
-* Types
-*
-**********************************************************************
-*/
-
-typedef struct {
- char *pBuffer;
- int BufferSize;
- int Cnt;
-} SEGGER_BUFFER_DESC;
-
-typedef struct {
- int CacheLineSize; // 0: No Cache. Most Systems such as ARM9 use a 32 bytes cache line size.
- void (*pfDMB) (void); // Optional DMB function for Data Memory Barrier to make sure all memory operations are completed.
- void (*pfClean) (void *p, unsigned NumBytes); // Optional clean function for cached memory.
- void (*pfInvalidate)(void *p, unsigned NumBytes); // Optional invalidate function for cached memory.
-} SEGGER_CACHE_CONFIG;
-
-/*********************************************************************
-*
-* Utility functions
-*
-**********************************************************************
-*/
-
-void SEGGER_ARM_memcpy (void *pDest, const void *pSrc, int NumBytes);
-void SEGGER_memcpy (void *pDest, const void *pSrc, int NumBytes);
-void SEGGER_memxor (void *pDest, const void *pSrc, unsigned NumBytes);
-void SEGGER_StoreChar (SEGGER_BUFFER_DESC *p, char c);
-void SEGGER_PrintUnsigned(SEGGER_BUFFER_DESC *pBufferDesc, U32 v, unsigned Base, int NumDigits);
-void SEGGER_PrintInt (SEGGER_BUFFER_DESC *pBufferDesc, I32 v, unsigned Base, unsigned NumDigits);
-int SEGGER_snprintf (char *pBuffer, int BufferSize, const char *sFormat, ...);
-
-
-#if defined(__cplusplus)
-} /* Make sure we have C-declarations in C++ programs */
-#endif
-
-#endif // Avoid multiple inclusion
-
-/*************************** End of file ****************************/
+/*********************************************************************
+* SEGGER Microcontroller GmbH & Co. KG *
+* The Embedded Experts *
+**********************************************************************
+* *
+* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
+* *
+* www.segger.com Support: support@segger.com *
+* *
+**********************************************************************
+* *
+* SEGGER SystemView * Real-time application analysis *
+* *
+**********************************************************************
+* *
+* All rights reserved. *
+* *
+* SEGGER strongly recommends to not make any changes *
+* to or modify the source code of this software in order to stay *
+* compatible with the RTT protocol and J-Link. *
+* *
+* Redistribution and use in source and binary forms, with or *
+* without modification, are permitted provided that the following *
+* conditions are met: *
+* *
+* o Redistributions of source code must retain the above copyright *
+* notice, this list of conditions and the following disclaimer. *
+* *
+* o Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the following *
+* disclaimer in the documentation and/or other materials provided *
+* with the distribution. *
+* *
+* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
+* nor the names of its contributors may be used to endorse or *
+* promote products derived from this software without specific *
+* prior written permission. *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
+* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
+* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
+* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
+* DAMAGE. *
+* *
+**********************************************************************
+* *
+* SystemView version: V2.42 *
+* *
+**********************************************************************
+----------------------------------------------------------------------
+File : SEGGER.h
+Purpose : Global types etc & general purpose utility functions
+---------------------------END-OF-HEADER------------------------------
+*/
+
+#ifndef SEGGER_H // Guard against multiple inclusion
+#define SEGGER_H
+
+#include "Global.h" // Type definitions: U8, U16, U32, I8, I16, I32
+
+#if defined(__cplusplus)
+extern "C" { /* Make sure we have C-declarations in C++ programs */
+#endif
+
+/*********************************************************************
+*
+* Keywords/specifiers
+*
+**********************************************************************
+*/
+
+#ifndef INLINE
+ #ifdef _WIN32
+ //
+ // Microsoft VC6 and newer.
+ // Force inlining without cost checking.
+ //
+ #define INLINE __forceinline
+ #else
+ #if (defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) || defined(__RX) || defined(__ICCRX__))
+ //
+ // Other known compilers.
+ //
+ #define INLINE inline
+ #else
+ //
+ // Unknown compilers.
+ //
+ #define INLINE
+ #endif
+ #endif
+#endif
+
+/*********************************************************************
+*
+* Function-like macros
+*
+**********************************************************************
+*/
+
+#define SEGGER_COUNTOF(a) (sizeof((a))/sizeof((a)[0]))
+#define SEGGER_MIN(a,b) (((a) < (b)) ? (a) : (b))
+#define SEGGER_MAX(a,b) (((a) > (b)) ? (a) : (b))
+
+/*********************************************************************
+*
+* Types
+*
+**********************************************************************
+*/
+
+typedef struct {
+ char *pBuffer;
+ int BufferSize;
+ int Cnt;
+} SEGGER_BUFFER_DESC;
+
+typedef struct {
+ int CacheLineSize; // 0: No Cache. Most Systems such as ARM9 use a 32 bytes cache line size.
+ void (*pfDMB) (void); // Optional DMB function for Data Memory Barrier to make sure all memory operations are completed.
+ void (*pfClean) (void *p, unsigned NumBytes); // Optional clean function for cached memory.
+ void (*pfInvalidate)(void *p, unsigned NumBytes); // Optional invalidate function for cached memory.
+} SEGGER_CACHE_CONFIG;
+
+/*********************************************************************
+*
+* Utility functions
+*
+**********************************************************************
+*/
+
+void SEGGER_ARM_memcpy (void *pDest, const void *pSrc, int NumBytes);
+void SEGGER_memcpy (void *pDest, const void *pSrc, int NumBytes);
+void SEGGER_memxor (void *pDest, const void *pSrc, unsigned NumBytes);
+void SEGGER_StoreChar (SEGGER_BUFFER_DESC *p, char c);
+void SEGGER_PrintUnsigned(SEGGER_BUFFER_DESC *pBufferDesc, U32 v, unsigned Base, int NumDigits);
+void SEGGER_PrintInt (SEGGER_BUFFER_DESC *pBufferDesc, I32 v, unsigned Base, unsigned NumDigits);
+int SEGGER_snprintf (char *pBuffer, int BufferSize, const char *sFormat, ...);
+
+
+#if defined(__cplusplus)
+} /* Make sure we have C-declarations in C++ programs */
+#endif
+
+#endif // Avoid multiple inclusion
+
+/*************************** End of file ****************************/
diff --git a/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW.c b/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW.c
index b588d723d0..c7460903b6 100644
--- a/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW.c
+++ b/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW.c
@@ -1,2763 +1,2763 @@
-/*********************************************************************
-* SEGGER Microcontroller GmbH & Co. KG *
-* The Embedded Experts *
-**********************************************************************
-* *
-* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
-* *
-* www.segger.com Support: support@segger.com *
-* *
-**********************************************************************
-* *
-* SEGGER SystemView * Real-time application analysis *
-* *
-**********************************************************************
-* *
-* All rights reserved. *
-* *
-* SEGGER strongly recommends to not make any changes *
-* to or modify the source code of this software in order to stay *
-* compatible with the RTT protocol and J-Link. *
-* *
-* Redistribution and use in source and binary forms, with or *
-* without modification, are permitted provided that the following *
-* conditions are met: *
-* *
-* o Redistributions of source code must retain the above copyright *
-* notice, this list of conditions and the following disclaimer. *
-* *
-* o Redistributions in binary form must reproduce the above *
-* copyright notice, this list of conditions and the following *
-* disclaimer in the documentation and/or other materials provided *
-* with the distribution. *
-* *
-* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
-* nor the names of its contributors may be used to endorse or *
-* promote products derived from this software without specific *
-* prior written permission. *
-* *
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
-* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
-* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
-* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
-* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
-* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
-* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
-* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
-* DAMAGE. *
-* *
-**********************************************************************
-* *
-* SystemView version: V2.42 *
-* *
-**********************************************************************
--------------------------- END-OF-HEADER -----------------------------
-
-File : SEGGER_SYSVIEW.c
-Purpose : System visualization API implementation.
-Revision: $Rev: 5927 $
-
-Additional information:
- Packet format:
- Packets with IDs 0..23 are standard packets with known structure.
- For efficiency, they do *NOT* contain a length field.
-
-
- Packets with IDs 24..31 are standard packets with extendible
- structure and contain a length field.
-
-
- Packets with IDs >= 32 always contain a length field.
-
-
- Packet IDs:
- 0.. 31 : Standard packets, known by SystemViewer.
- 32..1023 : OS-definable packets, described in a SystemView description file.
- 1024..2047 : User-definable packets, described in a SystemView description file.
- 2048..32767: Undefined.
-
- Data encoding:
- Basic types (int, short, char, ...):
- Basic types are encoded little endian with most-significant bit variant
- encoding.
- Each encoded byte contains 7 data bits [6:0] and the MSB continuation bit.
- The continuation bit indicates whether the next byte belongs to the data
- (bit set) or this is the last byte (bit clear).
- The most significant bits of data are encoded first, proceeding to the
- least significant bits in the final byte (little endian).
-
- Example encoding:
- Data: 0x1F4 (500)
- Encoded: 0xF4 (First 7 data bits 74 | Continuation bit)
- 0x03 (Second 7 data bits 03, no continuation)
-
- Data: 0xFFFFFFFF
- Encoded: 0xFF 0xFF 0xFF 0xFF 0x0F
-
- Data: 0xA2 (162), 0x03 (3), 0x7000
- Encoded: 0xA2 0x01 0x03 0x80 0xE0 0x01
-
- Byte arrays and strings:
- Byte arrays and strings are encoded as followed by the raw data.
- NumBytes is encoded as a basic type with a theoretical maximum of 4G.
-
- Example encoding:
- Data: "Hello World\0" (0x48 0x65 0x6C 0x6C 0x6F 0x20 0x57 0x6F 0x72 0x6C 0x64 0x00)
- Encoded: 0x0B 0x48 0x65 0x6C 0x6C 0x6F 0x20 0x57 0x6F 0x72 0x6C 0x64
-
- Examples packets:
- 01 F4 03 80 80 10 // Overflow packet. Data is a single U32.
- This packet means: 500 packets lost, Timestamp is 0x40000
-
- 02 0F 50 // ISR(15) Enter. Timestamp 80 (0x50)
-
- 03 20 // ISR Exit. Timestamp 32 (0x20) (Shortest possible packet.)
-
- Sample code for user defined Packets:
- #define MY_ID 0x400 // Any value between 0x400 and 0x7FF
- void SendMyPacket(unsigned Para0, unsigned Para1, const char* s) {
- U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + MAX_STR_LEN + 1];
- U8* pPayload;
- //
- pPayload = SEGGER_SYSVIEW_PPREPARE_PACKET(aPacket); // Prepare the packet for SystemView
- pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
- pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
- pPayload = SEGGER_SYSVIEW_EncodeString(pPayload, s, MAX_STR_LEN); // Add the string to the packet
- //
- SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, MY_ID); // Send the packet with EventId = MY_ID
- }
-
- #define MY_ID_1 0x401
- void SendOnePara(unsigned Para0) {
- SEGGER_SYSVIEW_RecordU32(MY_ID_1, Para0);
- }
-
-*/
-
-/*********************************************************************
-*
-* #include section
-*
-**********************************************************************
-*/
-
-#include "SEGGER_SYSVIEW_Int.h"
-#include "SEGGER_RTT.h"
-#include
-#include
-#include
-
-/*********************************************************************
-*
-* Defines, fixed
-*
-**********************************************************************
-*/
-#if SEGGER_SYSVIEW_ID_SHIFT
- #define SHRINK_ID(Id) (((Id) - _SYSVIEW_Globals.RAMBaseAddress) >> SEGGER_SYSVIEW_ID_SHIFT)
-#else
- #define SHRINK_ID(Id) ((Id) - _SYSVIEW_Globals.RAMBaseAddress)
-#endif
-
-#if SEGGER_SYSVIEW_RTT_CHANNEL > 0
- #define CHANNEL_ID_UP SEGGER_SYSVIEW_RTT_CHANNEL
- #define CHANNEL_ID_DOWN SEGGER_SYSVIEW_RTT_CHANNEL
-#else
- #define CHANNEL_ID_UP _SYSVIEW_Globals.UpChannel
- #define CHANNEL_ID_DOWN _SYSVIEW_Globals.DownChannel
-#endif
-
-/*********************************************************************
-*
-* Defines, configurable
-*
-**********************************************************************
-*/
-// Timestamps may be less than full 32-bits, in which case we need to zero
-// the unused bits to properly handle overflows.
-// Note that this is a quite common scenario, as a 32-bit time such as
-// SysTick might be scaled down to reduce bandwith
-// or a 16-bit hardware time might be used.
-#if SEGGER_SYSVIEW_TIMESTAMP_BITS < 32 // Eliminate unused bits in case hardware timestamps are less than 32 bits
- #define MAKE_DELTA_32BIT(Delta) Delta <<= 32 - SEGGER_SYSVIEW_TIMESTAMP_BITS; \
- Delta >>= 32 - SEGGER_SYSVIEW_TIMESTAMP_BITS;
-#else
- #define MAKE_DELTA_32BIT(Delta)
-#endif
-
-
-/*********************************************************************
-*
-* Defines, fixed
-*
-**********************************************************************
-*/
-#define ENABLE_STATE_OFF 0
-#define ENABLE_STATE_ON 1
-#define ENABLE_STATE_DROPPING 2
-
-#define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0)
-#define FORMAT_FLAG_PAD_ZERO (1u << 1)
-#define FORMAT_FLAG_PRINT_SIGN (1u << 2)
-#define FORMAT_FLAG_ALTERNATE (1u << 3)
-
-#define MODULE_EVENT_OFFSET (512)
-
-/*********************************************************************
-*
-* Types, local
-*
-**********************************************************************
-*/
-typedef struct {
- U8* pBuffer;
- U8* pPayload;
- U8* pPayloadStart;
- U32 Options;
- unsigned Cnt;
-} SEGGER_SYSVIEW_PRINTF_DESC;
-
-typedef struct {
- U8 EnableState; // 0: Disabled, 1: Enabled, (2: Dropping)
- U8 UpChannel;
- U8 RecursionCnt;
- U32 SysFreq;
- U32 CPUFreq;
- U32 LastTxTimeStamp;
- U32 RAMBaseAddress;
-#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
- U32 PacketCount;
-#else
- U32 DropCount;
- U8 DownChannel;
-#endif
- U32 DisabledEvents;
- const SEGGER_SYSVIEW_OS_API* pOSAPI;
- SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC* pfSendSysDesc;
-} SEGGER_SYSVIEW_GLOBALS;
-
-/*********************************************************************
-*
-* Function prototypes, required
-*
-**********************************************************************
-*/
-static void _SendPacket(U8* pStartPacket, U8* pEndPacket, unsigned int EventId);
-
-/*********************************************************************
-*
-* Static data
-*
-**********************************************************************
-*/
-static const U8 _abSync[10] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-#ifdef SEGGER_SYSVIEW_SECTION
- #if (defined __GNUC__)
- __attribute__ ((section (SEGGER_SYSVIEW_SECTION))) static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
- #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
- __attribute__ ((section (SEGGER_SYSVIEW_SECTION))) static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms
- #endif
- #elif (defined __ICCARM__) || (defined __ICCRX__)
- #pragma location=SEGGER_SYSVIEW_SECTION
- static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
- #pragma location=SEGGER_SYSVIEW_SECTION
- static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms
- #elif (defined __CC_ARM)
- __attribute__ ((section (SEGGER_SYSVIEW_SECTION), zero_init)) static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
- #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
- __attribute__ ((section (SEGGER_SYSVIEW_SECTION), zero_init)) static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms
- #endif
- #else
- static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
- #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
- static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms
- #endif
- #endif
-#else
- static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
- #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
- static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms
- #endif
-#endif
-
-static SEGGER_SYSVIEW_GLOBALS _SYSVIEW_Globals;
-
-static SEGGER_SYSVIEW_MODULE* _pFirstModule;
-static U8 _NumModules;
-
-/*********************************************************************
-*
-* Static code
-*
-**********************************************************************
-*/
-
-#define ENCODE_U32(pDest, Value) { \
- U8* pSysviewPointer; \
- U32 SysViewData; \
- pSysviewPointer = pDest; \
- SysViewData = Value; \
- while(SysViewData > 0x7F) { \
- *pSysviewPointer++ = (U8)(SysViewData | 0x80); \
- SysViewData >>= 7; \
- }; \
- *pSysviewPointer++ = (U8)SysViewData; \
- pDest = pSysviewPointer; \
- };
-
-
-
-#if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1)
-static U8 _aPacket[SEGGER_SYSVIEW_MAX_PACKET_SIZE];
-
-#define RECORD_START(PacketSize) SEGGER_SYSVIEW_LOCK(); \
- pPayloadStart = _PreparePacket(_aPacket);
-
-#define RECORD_END() SEGGER_SYSVIEW_UNLOCK()
-
-#else
-
-#define RECORD_START(PacketSize) U8 aPacket[(PacketSize)]; \
- pPayloadStart = _PreparePacket(aPacket); \
-
-#define RECORD_END()
-
-#endif
-
-/*********************************************************************
-*
-* _EncodeData()
-*
-* Function description
-* Encode a byte buffer in variable-length format.
-*
-* Parameters
-* pPayload - Pointer to where string will be encoded.
-* pSrc - Pointer to data buffer to be encoded.
-* NumBytes - Number of bytes in the buffer to be encoded.
-*
-* Return value
-* Pointer to the byte following the value, i.e. the first free
-* byte in the payload and the next position to store payload
-* content.
-*
-* Additional information
-* The data is encoded as a count byte followed by the contents
-* of the data buffer.
-* Make sure NumBytes + 1 bytes are free for the payload.
-*/
-static U8* _EncodeData(U8* pPayload, const char* pSrc, unsigned int NumBytes) {
- unsigned int n;
- //
- n = 0;
- *pPayload++ = NumBytes;
- while (n < NumBytes) {
- *pPayload++ = *pSrc++;
- n++;
- }
- return pPayload;
-}
-
-/*********************************************************************
-*
-* _EncodeStr()
-*
-* Function description
-* Encode a string in variable-length format.
-*
-* Parameters
-* pPayload - Pointer to where string will be encoded.
-* pText - String to encode.
-* Limit - Maximum number of characters to encode from string.
-*
-* Return value
-* Pointer to the byte following the value, i.e. the first free
-* byte in the payload and the next position to store payload
-* content.
-*
-* Additional information
-* The string is encoded as a count byte followed by the contents
-* of the string.
-* No more than 1 + Limit bytes will be encoded to the payload.
-*/
-static U8 *_EncodeStr(U8 *pPayload, const char *pText, unsigned int Limit) {
- unsigned int n;
- unsigned int Len;
- //
- // Compute string len
- //
- Len = 0;
- while(*(pText + Len) != 0) {
- Len++;
- }
- if (Len > Limit) {
- Len = Limit;
- }
- //
- // Write Len
- //
- if (Len < 255) {
- *pPayload++ = Len;
- } else {
- *pPayload++ = 255;
- *pPayload++ = (Len & 255);
- *pPayload++ = ((Len >> 8) & 255);
- }
- //
- // copy string
- //
- n = 0;
- while (n < Len) {
- *pPayload++ = *pText++;
- n++;
- }
- return pPayload;
-}
-
-/*********************************************************************
-*
-* _PreparePacket()
-*
-* Function description
-* Prepare a SystemView event packet header.
-*
-* Parameters
-* pPacket - Pointer to start of packet to initialize.
-*
-* Return value
-* Pointer to first byte of packet payload.
-*
-* Additional information
-* The payload length and evnetId are not initialized.
-* PreparePacket only reserves space for them and they are
-* computed and filled in by the sending function.
-*/
-static U8* _PreparePacket(U8* pPacket) {
- return pPacket + 4;
-}
-
-/*********************************************************************
-*
-* _HandleIncomingPacket()
-*
-* Function description
-* Read an incoming command from the down channel and process it.
-*
-* Additional information
-* This function is called each time after sending a packet.
-* Processing incoming packets is done asynchronous. SystemView might
-* already have sent event packets after the host has sent a command.
-*/
-#if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
-static void _HandleIncomingPacket(void) {
- U8 Cmd;
- int Status;
- //
- Status = SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1);
- if (Status > 0) {
- switch (Cmd) {
- case SEGGER_SYSVIEW_COMMAND_ID_START:
- SEGGER_SYSVIEW_Start();
- break;
- case SEGGER_SYSVIEW_COMMAND_ID_STOP:
- SEGGER_SYSVIEW_Stop();
- break;
- case SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME:
- SEGGER_SYSVIEW_RecordSystime();
- break;
- case SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST:
- SEGGER_SYSVIEW_SendTaskList();
- break;
- case SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC:
- SEGGER_SYSVIEW_GetSysDesc();
- break;
- case SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES:
- SEGGER_SYSVIEW_SendNumModules();
- break;
- case SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC:
- SEGGER_SYSVIEW_SendModuleDescription();
- break;
- case SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE:
- Status = SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1);
- if (Status > 0) {
- SEGGER_SYSVIEW_SendModule(Cmd);
- }
- break;
- default:
- if (Cmd >= 128) { // Unknown extended command. Dummy read its parameter.
- SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1);
- }
- break;
- }
- }
-}
-#endif // (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
-
-/*********************************************************************
-*
-* _TrySendOverflowPacket()
-*
-* Function description
-* Try to transmit an SystemView Overflow packet containing the
-* number of dropped packets.
-*
-* Additional information
-* Format as follows:
-* 01 Max. packet len is 1 + 5 + 5 = 11
-*
-* Example packets sent
-* 01 20 40
-*
-* Return value
-* !=0: Success, Message sent (stored in RTT-Buffer)
-* ==0: Buffer full, Message *NOT* stored
-*
-*/
-#if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
-static int _TrySendOverflowPacket(void) {
- U32 TimeStamp;
- I32 Delta;
- int Status;
- U8 aPacket[11];
- U8* pPayload;
-
- aPacket[0] = SYSVIEW_EVTID_OVERFLOW; // 1
- pPayload = &aPacket[1];
- ENCODE_U32(pPayload, _SYSVIEW_Globals.DropCount);
- //
- // Compute time stamp delta and append it to packet.
- //
- TimeStamp = SEGGER_SYSVIEW_GET_TIMESTAMP();
- Delta = TimeStamp - _SYSVIEW_Globals.LastTxTimeStamp;
- MAKE_DELTA_32BIT(Delta);
- ENCODE_U32(pPayload, Delta);
- //
- // Try to store packet in RTT buffer and update time stamp when this was successful
- //
- Status = SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, aPacket, pPayload - aPacket);
- if (Status) {
- _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp;
- _SYSVIEW_Globals.EnableState--; // EnableState has been 2, will be 1. Always.
- } else {
- _SYSVIEW_Globals.DropCount++;
- }
- //
- return Status;
-}
-#endif // (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
-
-/*********************************************************************
-*
-* _SendSyncInfo()
-*
-* Function description
-* Send SystemView sync packet and system information in
-* post mortem mode.
-*
-* Additional information
-* Sync is 10 * 0x00 without timestamp
-*/
-#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
-static void _SendSyncInfo(void) {
- //
- // Add sync packet ( 10 * 0x00)
- // Send system description
- // Send system time
- // Send task list
- // Send module description
- // Send module information
- //
- SEGGER_RTT_WriteWithOverwriteNoLock(CHANNEL_ID_UP, _abSync, 10);
- SEGGER_SYSVIEW_RecordVoid(SYSVIEW_EVTID_TRACE_START);
- {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, _SYSVIEW_Globals.SysFreq);
- ENCODE_U32(pPayload, _SYSVIEW_Globals.CPUFreq);
- ENCODE_U32(pPayload, _SYSVIEW_Globals.RAMBaseAddress);
- ENCODE_U32(pPayload, SEGGER_SYSVIEW_ID_SHIFT);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_INIT);
- RECORD_END();
- }
- if (_SYSVIEW_Globals.pfSendSysDesc) {
- _SYSVIEW_Globals.pfSendSysDesc();
- }
- SEGGER_SYSVIEW_RecordSystime();
- SEGGER_SYSVIEW_SendTaskList();
- if (_NumModules > 0) {
- SEGGER_SYSVIEW_SendNumModules();
- for (int n = 0; n < _NumModules; n++) {
- SEGGER_SYSVIEW_SendModule(n);
- }
- SEGGER_SYSVIEW_SendModuleDescription();
- }
-}
-#endif // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
-
-/*********************************************************************
-*
-* _SendPacket()
-*
-* Function description
-* Send a SystemView packet over RTT. RTT channel and mode are
-* configured by macros when the SystemView component is initialized.
-* This function takes care of maintaining the packet drop count
-* and sending overflow packets when necessary.
-* The packet must be passed without Id and Length because this
-* function prepends it to the packet before transmission.
-*
-* Parameters
-* pStartPacket - Pointer to start of packet payload.
-* There must be at least 4 bytes free to prepend Id and Length.
-* pEndPacket - Pointer to end of packet payload.
-* EventId - Id of the event to send.
-*
-*/
-static void _SendPacket(U8* pStartPacket, U8* pEndPacket, unsigned int EventId) {
- unsigned int NumBytes;
- U32 TimeStamp;
- U32 Delta;
-#if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
- int Status;
-#endif
-
-#if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0)
- SEGGER_SYSVIEW_LOCK();
-#endif
-
-#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
- if (_SYSVIEW_Globals.EnableState == 0) {
- goto SendDone;
- }
-#else
- if (_SYSVIEW_Globals.EnableState == 1) { // Enabled, no dropped packets remaining
- goto Send;
- }
- if (_SYSVIEW_Globals.EnableState == 0) {
- goto SendDone;
- }
- //
- // Handle buffer full situations:
- // Have packets been dropped before because buffer was full?
- // In this case try to send and overflow packet.
- //
- if (_SYSVIEW_Globals.EnableState == 2) {
- _TrySendOverflowPacket();
- if (_SYSVIEW_Globals.EnableState != 1) {
- goto SendDone;
- }
- }
-Send:
-#endif
- //
- // Check if event is disabled from being recorded.
- //
- if (EventId < 32) {
- if (_SYSVIEW_Globals.DisabledEvents & ((U32)1u << EventId)) {
- goto SendDone;
- }
- }
- //
- // Prepare actual packet.
- // If it is a known packet, prepend eventId only,
- // otherwise prepend packet length and eventId.
- //
- if (EventId < 24) {
- *--pStartPacket = EventId;
- } else {
- NumBytes = pEndPacket - pStartPacket;
- if (NumBytes > 127) {
- *--pStartPacket = (NumBytes >> 7);
- *--pStartPacket = NumBytes | 0x80;
- } else {
- *--pStartPacket = NumBytes;
- }
- if (EventId > 127) {
- *--pStartPacket = (EventId >> 7);
- *--pStartPacket = EventId | 0x80;
- } else {
- *--pStartPacket = EventId;
- }
- }
- //
- // Compute time stamp delta and append it to packet.
- //
- TimeStamp = SEGGER_SYSVIEW_GET_TIMESTAMP();
- Delta = TimeStamp - _SYSVIEW_Globals.LastTxTimeStamp;
- MAKE_DELTA_32BIT(Delta);
- ENCODE_U32(pEndPacket, Delta);
-#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
- //
- // Store packet in RTT buffer by overwriting old data and update time stamp
- //
- SEGGER_RTT_WriteWithOverwriteNoLock(CHANNEL_ID_UP, pStartPacket, pEndPacket - pStartPacket);
- _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp;
-#else
- //
- // Try to store packet in RTT buffer and update time stamp when this was successful
- //
- Status = SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, pStartPacket, pEndPacket - pStartPacket);
- if (Status) {
- _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp;
- } else {
- _SYSVIEW_Globals.EnableState++; // EnableState has been 1, will be 2. Always.
- }
-#endif
-
-#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
- //
- // Add sync and system information periodically if we are in post mortem mode
- //
- if (_SYSVIEW_Globals.RecursionCnt == 0) { // Avoid uncontrolled nesting. This way, this routine can call itself once, but no more often than that.
- _SYSVIEW_Globals.RecursionCnt = 1;
- if (_SYSVIEW_Globals.PacketCount++ & (1 << SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT)) {
- _SendSyncInfo();
- _SYSVIEW_Globals.PacketCount = 0;
- }
- _SYSVIEW_Globals.RecursionCnt = 0;
- }
-SendDone:
- ; // Avoid "label at end of compound statement" error when using static buffer
-#else
-SendDone:
- //
- // Check if host is sending data which needs to be processed.
- // Note that since this code is called for every packet, it is very time critical, so we do
- // only what is really needed here, which is checking if there is any data
- //
- if (SEGGER_RTT_HASDATA(CHANNEL_ID_DOWN)) {
- if (_SYSVIEW_Globals.RecursionCnt == 0) { // Avoid uncontrolled nesting. This way, this routine can call itself once, but no more often than that.
- _SYSVIEW_Globals.RecursionCnt = 1;
- _HandleIncomingPacket();
- _SYSVIEW_Globals.RecursionCnt = 0;
- }
- }
-#endif
- //
-#if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0)
- SEGGER_SYSVIEW_UNLOCK(); // We are done. Unlock and return
-#endif
-}
-
-#ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
-/*********************************************************************
-*
-* _APrintHost()
-*
-* Function description
-* Prepares a string and its parameters to be formatted on the host.
-*
-* Parameters
-* s Pointer to format string.
-* Options Options to be sent to the host.
-* pArguments Pointer to array of arguments for the format string.
-* NumArguments Number of arguments in the array.
-*/
-static void _APrintHost(const char* s, U32 Options, U32* pArguments, U32 NumArguments) {
- U8* pPayload;
- U8* pPayloadStart;
-
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32);
- pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
- ENCODE_U32(pPayload, Options);
- ENCODE_U32(pPayload, NumArguments);
- while (NumArguments--) {
- ENCODE_U32(pPayload, (*pArguments++));
- }
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* _VPrintHost()
-*
-* Function description
-* Prepares a string and its parameters to be formatted on the host.
-*
-* Parameters
-* s Pointer to format string.
-* Options Options to be sent to the host.
-* pParamList Pointer to the list of arguments for the format string.
-*/
-static void _VPrintHost(const char* s, U32 Options, va_list* pParamList) {
- U32 aParas[SEGGER_SYSVIEW_MAX_ARGUMENTS];
- U32 NumArguments;
- const char* p;
-
- p = s;
- NumArguments = 0;
- while (*p) {
- if (*p == '%') {
- aParas[NumArguments++] = va_arg(*pParamList, int);
- if (NumArguments == SEGGER_SYSVIEW_MAX_ARGUMENTS) {
- break;
- }
- }
- p++;
- }
- _APrintHost(s, Options, aParas, NumArguments);
-}
-
-/*********************************************************************
-*
-* _StoreChar()
-*
-* Function description
-* Stores a character in the printf-buffer and sends the buffer when
-* it is filled.
-*
-* Parameters
-* p Pointer to the buffer description.
-* c Character to be printed.
-*/
-static void _StoreChar(SEGGER_SYSVIEW_PRINTF_DESC * p, char c) {
- unsigned int Cnt;
- U8* pPayload;
- U32 Options;
-
- Cnt = p->Cnt;
- if ((Cnt + 1u) <= SEGGER_SYSVIEW_MAX_STRING_LEN) {
- *(p->pPayload++) = c;
- p->Cnt = Cnt + 1u;
- }
- //
- // Write part of string, when the buffer is full
- //
- if (p->Cnt == SEGGER_SYSVIEW_MAX_STRING_LEN) {
- *(p->pPayloadStart) = p->Cnt;
- pPayload = p->pPayload;
- Options = p->Options;
- ENCODE_U32(pPayload, Options);
- ENCODE_U32(pPayload, 0);
- _SendPacket(p->pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
- p->pPayloadStart = _PreparePacket(p->pBuffer);
- p->pPayload = p->pPayloadStart + 1u;
- p->Cnt = 0u;
- }
-}
-
-/*********************************************************************
-*
-* _PrintUnsigned()
-*
-* Function description
-* Print an unsigned integer with the given formatting into the
-* formatted string.
-*
-* Parameters
-* pBufferDesc Pointer to the buffer description.
-* v Value to be printed.
-* Base Base of the value.
-* NumDigits Number of digits to be printed.
-* FieldWidth Width of the printed field.
-* FormatFlags Flags for formatting the value.
-*/
-static void _PrintUnsigned(SEGGER_SYSVIEW_PRINTF_DESC * pBufferDesc, unsigned int v, unsigned int Base, unsigned int NumDigits, unsigned int FieldWidth, unsigned int FormatFlags) {
- static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
- unsigned int Div;
- unsigned int Digit;
- unsigned int Number;
- unsigned int Width;
- char c;
-
- Number = v;
- Digit = 1u;
- //
- // Get actual field width
- //
- Width = 1u;
- while (Number >= Base) {
- Number = (Number / Base);
- Width++;
- }
- if (NumDigits > Width) {
- Width = NumDigits;
- }
- //
- // Print leading chars if necessary
- //
- if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
- if (FieldWidth != 0u) {
- if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
- c = '0';
- } else {
- c = ' ';
- }
- while ((FieldWidth != 0u) && (Width < FieldWidth)) {
- FieldWidth--;
- _StoreChar(pBufferDesc, c);
- }
- }
- }
- //
- // Compute Digit.
- // Loop until Digit has the value of the highest digit required.
- // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100.
- //
- while (1) {
- if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned)
- NumDigits--;
- } else {
- Div = v / Digit;
- if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done
- break;
- }
- }
- Digit *= Base;
- }
- //
- // Output digits
- //
- do {
- Div = v / Digit;
- v -= Div * Digit;
- _StoreChar(pBufferDesc, _aV2C[Div]);
- Digit /= Base;
- } while (Digit);
- //
- // Print trailing spaces if necessary
- //
- if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
- if (FieldWidth != 0u) {
- while ((FieldWidth != 0u) && (Width < FieldWidth)) {
- FieldWidth--;
- _StoreChar(pBufferDesc, ' ');
- }
- }
- }
-}
-
-/*********************************************************************
-*
-* _PrintInt()
-*
-* Function description
-* Print a signed integer with the given formatting into the
-* formatted string.
-*
-* Parameters
-* pBufferDesc Pointer to the buffer description.
-* v Value to be printed.
-* Base Base of the value.
-* NumDigits Number of digits to be printed.
-* FieldWidth Width of the printed field.
-* FormatFlags Flags for formatting the value.
-*/
-static void _PrintInt(SEGGER_SYSVIEW_PRINTF_DESC * pBufferDesc, int v, unsigned int Base, unsigned int NumDigits, unsigned int FieldWidth, unsigned int FormatFlags) {
- unsigned int Width;
- int Number;
-
- Number = (v < 0) ? -v : v;
-
- //
- // Get actual field width
- //
- Width = 1u;
- while (Number >= (int)Base) {
- Number = (Number / (int)Base);
- Width++;
- }
- if (NumDigits > Width) {
- Width = NumDigits;
- }
- if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
- FieldWidth--;
- }
-
- //
- // Print leading spaces if necessary
- //
- if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
- if (FieldWidth != 0u) {
- while ((FieldWidth != 0u) && (Width < FieldWidth)) {
- FieldWidth--;
- _StoreChar(pBufferDesc, ' ');
- }
- }
- }
- //
- // Print sign if necessary
- //
- if (v < 0) {
- v = -v;
- _StoreChar(pBufferDesc, '-');
- } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
- _StoreChar(pBufferDesc, '+');
- } else {
-
- }
- //
- // Print leading zeros if necessary
- //
- if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
- if (FieldWidth != 0u) {
- while ((FieldWidth != 0u) && (Width < FieldWidth)) {
- FieldWidth--;
- _StoreChar(pBufferDesc, '0');
- }
- }
- }
- //
- // Print number without sign
- //
- _PrintUnsigned(pBufferDesc, (unsigned int)v, Base, NumDigits, FieldWidth, FormatFlags);
-}
-
-/*********************************************************************
-*
-* _VPrintTarget()
-*
-* Function description
-* Stores a formatted string.
-* This data is read by the host.
-*
-* Parameters
-* sFormat Pointer to format string.
-* Options Options to be sent to the host.
-* pParamList Pointer to the list of arguments for the format string.
-*/
-static void _VPrintTarget(const char* sFormat, U32 Options, va_list* pParamList) {
- SEGGER_SYSVIEW_PRINTF_DESC BufferDesc;
- char c;
- int v;
- unsigned int NumDigits;
- unsigned int FormatFlags;
- unsigned int FieldWidth;
- U8* pPayloadStart;
-#if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 1 + 2 * SEGGER_SYSVIEW_QUANTA_U32);
- SEGGER_SYSVIEW_LOCK();
-#else
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 1 + 2 * SEGGER_SYSVIEW_QUANTA_U32);
-#endif
-
-#if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0
- BufferDesc.pBuffer = aPacket;
-#else
- BufferDesc.pBuffer = _aPacket;
-#endif
- BufferDesc.Cnt = 0u;
- BufferDesc.pPayloadStart = pPayloadStart;
- BufferDesc.pPayload = BufferDesc.pPayloadStart + 1u;
- BufferDesc.Options = Options;
-
- do {
- c = *sFormat;
- sFormat++;
- if (c == 0u) {
- break;
- }
- if (c == '%') {
- //
- // Filter out flags
- //
- FormatFlags = 0u;
- v = 1;
- do {
- c = *sFormat;
- switch (c) {
- case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
- case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break;
- case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break;
- case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break;
- default: v = 0; break;
- }
- } while (v);
- //
- // filter out field with
- //
- FieldWidth = 0u;
- do {
- c = *sFormat;
- if ((c < '0') || (c > '9')) {
- break;
- }
- sFormat++;
- FieldWidth = (FieldWidth * 10u) + ((unsigned int)c - '0');
- } while (1);
-
- //
- // Filter out precision (number of digits to display)
- //
- NumDigits = 0u;
- c = *sFormat;
- if (c == '.') {
- sFormat++;
- do {
- c = *sFormat;
- if ((c < '0') || (c > '9')) {
- break;
- }
- sFormat++;
- NumDigits = NumDigits * 10u + ((unsigned int)c - '0');
- } while (1);
- }
- //
- // Filter out length modifier
- //
- c = *sFormat;
- do {
- if ((c == 'l') || (c == 'h')) {
- c = *sFormat;
- sFormat++;
- } else {
- break;
- }
- } while (1);
- //
- // Handle specifiers
- //
- switch (c) {
- case 'c': {
- char c0;
- v = va_arg(*pParamList, int);
- c0 = (char)v;
- _StoreChar(&BufferDesc, c0);
- break;
- }
- case 'd':
- v = va_arg(*pParamList, int);
- _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
- break;
- case 'u':
- v = va_arg(*pParamList, int);
- _PrintUnsigned(&BufferDesc, (unsigned int)v, 10u, NumDigits, FieldWidth, FormatFlags);
- break;
- case 'x':
- case 'X':
- v = va_arg(*pParamList, int);
- _PrintUnsigned(&BufferDesc, (unsigned int)v, 16u, NumDigits, FieldWidth, FormatFlags);
- break;
- case 'p':
- v = va_arg(*pParamList, int);
- _PrintUnsigned(&BufferDesc, (unsigned int)v, 16u, 8u, 8u, 0u);
- break;
- case '%':
- _StoreChar(&BufferDesc, '%');
- break;
- default:
- break;
- }
- sFormat++;
- } else {
- _StoreChar(&BufferDesc, c);
- }
- } while (*sFormat);
-
- //
- // Write remaining data, if any
- //
- if (BufferDesc.Cnt != 0u) {
- *(BufferDesc.pPayloadStart) = BufferDesc.Cnt;
- ENCODE_U32(BufferDesc.pPayload, BufferDesc.Options);
- ENCODE_U32(BufferDesc.pPayload, 0);
- _SendPacket(BufferDesc.pPayloadStart, BufferDesc.pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
- }
-#if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0
- SEGGER_SYSVIEW_UNLOCK();
- RECORD_END();
-#else
- RECORD_END();
-#endif
-}
-#endif // SEGGER_SYSVIEW_EXCLUDE_PRINTF
-
-/*********************************************************************
-*
-* Public functions
-*
-**********************************************************************
-*/
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_Init()
-*
-* Function description
-* Initializes the SYSVIEW module.
-* Must be called before SystemViewer attaches to the system.
-*
-* Parameters
-* SysFreq - Frequency of timestamp, i.e. CPU core clock frequency.
-* CPUFreq - CPU core clock frequency.
-* pOSAPI - Pointer to the API structure for OS-specific functions.
-* pfSendSysDesc - Pointer to SendSysDesc callback function.
-*
-* Additional information
-* This function initializes the RTT channel used to transport
-* SEGGER SystemView packets.
-* The channel is assigned the label "SysView" for client software
-* to identify the SystemView channel.
-*
-* Notes
-* The channel is configured by the macro SEGGER_SYSVIEW_RTT_CHANNEL.
-*/
-void SEGGER_SYSVIEW_Init(U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc) {
-#ifdef SEGGER_RTT_SECTION
- //
- // Explicitly initialize the RTT Control Block if it is in its dedicated section.
- //
- SEGGER_RTT_Init();
-#endif
-#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
-#if SEGGER_SYSVIEW_RTT_CHANNEL > 0
- SEGGER_RTT_ConfigUpBuffer(SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
-#else
- _SYSVIEW_Globals.UpChannel = SEGGER_RTT_AllocUpBuffer ("SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
-#endif
- _SYSVIEW_Globals.RAMBaseAddress = SEGGER_SYSVIEW_ID_BASE;
- _SYSVIEW_Globals.LastTxTimeStamp = SEGGER_SYSVIEW_GET_TIMESTAMP();
- _SYSVIEW_Globals.pOSAPI = pOSAPI;
- _SYSVIEW_Globals.SysFreq = SysFreq;
- _SYSVIEW_Globals.CPUFreq = CPUFreq;
- _SYSVIEW_Globals.pfSendSysDesc = pfSendSysDesc;
- _SYSVIEW_Globals.EnableState = 0;
- _SYSVIEW_Globals.PacketCount = 0;
-#else // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
-#if SEGGER_SYSVIEW_RTT_CHANNEL > 0
- SEGGER_RTT_ConfigUpBuffer (SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
- SEGGER_RTT_ConfigDownBuffer (SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_DownBuffer[0], sizeof(_DownBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
-#else
- _SYSVIEW_Globals.UpChannel = SEGGER_RTT_AllocUpBuffer ("SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
- //
- // TODO: Use SEGGER_RTT_AllocDownBuffer when SystemViewer is able to handle another Down Channel than Up Channel.
- //
- _SYSVIEW_Globals.DownChannel = _SYSVIEW_Globals.UpChannel;
- SEGGER_RTT_ConfigDownBuffer (_SYSVIEW_Globals.DownChannel, "SysView", &_DownBuffer[0], sizeof(_DownBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
-#endif
- _SYSVIEW_Globals.RAMBaseAddress = SEGGER_SYSVIEW_ID_BASE;
- _SYSVIEW_Globals.LastTxTimeStamp = SEGGER_SYSVIEW_GET_TIMESTAMP();
- _SYSVIEW_Globals.pOSAPI = pOSAPI;
- _SYSVIEW_Globals.SysFreq = SysFreq;
- _SYSVIEW_Globals.CPUFreq = CPUFreq;
- _SYSVIEW_Globals.pfSendSysDesc = pfSendSysDesc;
- _SYSVIEW_Globals.EnableState = 0;
-#endif // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_SetRAMBase()
-*
-* Function description
-* Sets the RAM base address, which is subtracted from IDs in order
-* to save bandwidth.
-*
-* Parameters
-* RAMBaseAddress - Lowest RAM Address. (i.e. 0x20000000 on most Cortex-M)
-*/
-void SEGGER_SYSVIEW_SetRAMBase(U32 RAMBaseAddress) {
- _SYSVIEW_Globals.RAMBaseAddress = RAMBaseAddress;
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordVoid()
-*
-* Function description
-* Formats and sends a SystemView packet with an empty payload.
-*
-* Parameters
-* EventID - SystemView event ID.
-*/
-void SEGGER_SYSVIEW_RecordVoid(unsigned int EventID) {
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
- //
- _SendPacket(pPayloadStart, pPayloadStart, EventID);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordU32()
-*
-* Function description
-* Formats and sends a SystemView packet containing a single U32
-* parameter payload.
-*
-* Parameters
-* EventID - SystemView event ID.
-* Value - The 32-bit parameter encoded to SystemView packet payload.
-*/
-void SEGGER_SYSVIEW_RecordU32(unsigned int EventID, U32 Value) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, Value);
- _SendPacket(pPayloadStart, pPayload, EventID);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordU32x2()
-*
-* Function description
-* Formats and sends a SystemView packet containing 2 U32 parameter payload.
-*
-* Parameters
-* EventID - SystemView event ID.
-* Para0 - The 32-bit parameter encoded to SystemView packet payload.
-* Para1 - The 32-bit parameter encoded to SystemView packet payload.
-*/
-void SEGGER_SYSVIEW_RecordU32x2(unsigned int EventID, U32 Para0, U32 Para1) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, Para0);
- ENCODE_U32(pPayload, Para1);
- _SendPacket(pPayloadStart, pPayload, EventID);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordU32x3()
-*
-* Function description
-* Formats and sends a SystemView packet containing 3 U32 parameter payload.
-*
-* Parameters
-* EventID - SystemView event ID.
-* Para0 - The 32-bit parameter encoded to SystemView packet payload.
-* Para1 - The 32-bit parameter encoded to SystemView packet payload.
-* Para2 - The 32-bit parameter encoded to SystemView packet payload.
-*/
-void SEGGER_SYSVIEW_RecordU32x3(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 3 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, Para0);
- ENCODE_U32(pPayload, Para1);
- ENCODE_U32(pPayload, Para2);
- _SendPacket(pPayloadStart, pPayload, EventID);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordU32x4()
-*
-* Function description
-* Formats and sends a SystemView packet containing 4 U32 parameter payload.
-*
-* Parameters
-* EventID - SystemView event ID.
-* Para0 - The 32-bit parameter encoded to SystemView packet payload.
-* Para1 - The 32-bit parameter encoded to SystemView packet payload.
-* Para2 - The 32-bit parameter encoded to SystemView packet payload.
-* Para3 - The 32-bit parameter encoded to SystemView packet payload.
-*/
-void SEGGER_SYSVIEW_RecordU32x4(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, Para0);
- ENCODE_U32(pPayload, Para1);
- ENCODE_U32(pPayload, Para2);
- ENCODE_U32(pPayload, Para3);
- _SendPacket(pPayloadStart, pPayload, EventID);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordU32x5()
-*
-* Function description
-* Formats and sends a SystemView packet containing 5 U32 parameter payload.
-*
-* Parameters
-* EventID - SystemView event ID.
-* Para0 - The 32-bit parameter encoded to SystemView packet payload.
-* Para1 - The 32-bit parameter encoded to SystemView packet payload.
-* Para2 - The 32-bit parameter encoded to SystemView packet payload.
-* Para3 - The 32-bit parameter encoded to SystemView packet payload.
-* Para4 - The 32-bit parameter encoded to SystemView packet payload.
-*/
-void SEGGER_SYSVIEW_RecordU32x5(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, Para0);
- ENCODE_U32(pPayload, Para1);
- ENCODE_U32(pPayload, Para2);
- ENCODE_U32(pPayload, Para3);
- ENCODE_U32(pPayload, Para4);
- _SendPacket(pPayloadStart, pPayload, EventID);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordU32x6()
-*
-* Function description
-* Formats and sends a SystemView packet containing 6 U32 parameter payload.
-*
-* Parameters
-* EventID - SystemView event ID.
-* Para0 - The 32-bit parameter encoded to SystemView packet payload.
-* Para1 - The 32-bit parameter encoded to SystemView packet payload.
-* Para2 - The 32-bit parameter encoded to SystemView packet payload.
-* Para3 - The 32-bit parameter encoded to SystemView packet payload.
-* Para4 - The 32-bit parameter encoded to SystemView packet payload.
-* Para5 - The 32-bit parameter encoded to SystemView packet payload.
-*/
-void SEGGER_SYSVIEW_RecordU32x6(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 6 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, Para0);
- ENCODE_U32(pPayload, Para1);
- ENCODE_U32(pPayload, Para2);
- ENCODE_U32(pPayload, Para3);
- ENCODE_U32(pPayload, Para4);
- ENCODE_U32(pPayload, Para5);
- _SendPacket(pPayloadStart, pPayload, EventID);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordU32x7()
-*
-* Function description
-* Formats and sends a SystemView packet containing 7 U32 parameter payload.
-*
-* Parameters
-* EventID - SystemView event ID.
-* Para0 - The 32-bit parameter encoded to SystemView packet payload.
-* Para1 - The 32-bit parameter encoded to SystemView packet payload.
-* Para2 - The 32-bit parameter encoded to SystemView packet payload.
-* Para3 - The 32-bit parameter encoded to SystemView packet payload.
-* Para4 - The 32-bit parameter encoded to SystemView packet payload.
-* Para5 - The 32-bit parameter encoded to SystemView packet payload.
-* Para6 - The 32-bit parameter encoded to SystemView packet payload.
-*/
-void SEGGER_SYSVIEW_RecordU32x7(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 7 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, Para0);
- ENCODE_U32(pPayload, Para1);
- ENCODE_U32(pPayload, Para2);
- ENCODE_U32(pPayload, Para3);
- ENCODE_U32(pPayload, Para4);
- ENCODE_U32(pPayload, Para5);
- ENCODE_U32(pPayload, Para6);
- _SendPacket(pPayloadStart, pPayload, EventID);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordU32x8()
-*
-* Function description
-* Formats and sends a SystemView packet containing 8 U32 parameter payload.
-*
-* Parameters
-* EventID - SystemView event ID.
-* Para0 - The 32-bit parameter encoded to SystemView packet payload.
-* Para1 - The 32-bit parameter encoded to SystemView packet payload.
-* Para2 - The 32-bit parameter encoded to SystemView packet payload.
-* Para3 - The 32-bit parameter encoded to SystemView packet payload.
-* Para4 - The 32-bit parameter encoded to SystemView packet payload.
-* Para5 - The 32-bit parameter encoded to SystemView packet payload.
-* Para6 - The 32-bit parameter encoded to SystemView packet payload.
-* Para7 - The 32-bit parameter encoded to SystemView packet payload.
-*/
-void SEGGER_SYSVIEW_RecordU32x8(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 8 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, Para0);
- ENCODE_U32(pPayload, Para1);
- ENCODE_U32(pPayload, Para2);
- ENCODE_U32(pPayload, Para3);
- ENCODE_U32(pPayload, Para4);
- ENCODE_U32(pPayload, Para5);
- ENCODE_U32(pPayload, Para6);
- ENCODE_U32(pPayload, Para7);
- _SendPacket(pPayloadStart, pPayload, EventID);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordU32x9()
-*
-* Function description
-* Formats and sends a SystemView packet containing 9 U32 parameter payload.
-*
-* Parameters
-* EventID - SystemView event ID.
-* Para0 - The 32-bit parameter encoded to SystemView packet payload.
-* Para1 - The 32-bit parameter encoded to SystemView packet payload.
-* Para2 - The 32-bit parameter encoded to SystemView packet payload.
-* Para3 - The 32-bit parameter encoded to SystemView packet payload.
-* Para4 - The 32-bit parameter encoded to SystemView packet payload.
-* Para5 - The 32-bit parameter encoded to SystemView packet payload.
-* Para6 - The 32-bit parameter encoded to SystemView packet payload.
-* Para7 - The 32-bit parameter encoded to SystemView packet payload.
-* Para8 - The 32-bit parameter encoded to SystemView packet payload.
-*/
-void SEGGER_SYSVIEW_RecordU32x9(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 9 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, Para0);
- ENCODE_U32(pPayload, Para1);
- ENCODE_U32(pPayload, Para2);
- ENCODE_U32(pPayload, Para3);
- ENCODE_U32(pPayload, Para4);
- ENCODE_U32(pPayload, Para5);
- ENCODE_U32(pPayload, Para6);
- ENCODE_U32(pPayload, Para7);
- ENCODE_U32(pPayload, Para8);
- _SendPacket(pPayloadStart, pPayload, EventID);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordU32x10()
-*
-* Function description
-* Formats and sends a SystemView packet containing 10 U32 parameter payload.
-*
-* Parameters
-* EventID - SystemView event ID.
-* Para0 - The 32-bit parameter encoded to SystemView packet payload.
-* Para1 - The 32-bit parameter encoded to SystemView packet payload.
-* Para2 - The 32-bit parameter encoded to SystemView packet payload.
-* Para3 - The 32-bit parameter encoded to SystemView packet payload.
-* Para4 - The 32-bit parameter encoded to SystemView packet payload.
-* Para5 - The 32-bit parameter encoded to SystemView packet payload.
-* Para6 - The 32-bit parameter encoded to SystemView packet payload.
-* Para7 - The 32-bit parameter encoded to SystemView packet payload.
-* Para8 - The 32-bit parameter encoded to SystemView packet payload.
-* Para9 - The 32-bit parameter encoded to SystemView packet payload.
-*/
-void SEGGER_SYSVIEW_RecordU32x10(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8, U32 Para9) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 10 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, Para0);
- ENCODE_U32(pPayload, Para1);
- ENCODE_U32(pPayload, Para2);
- ENCODE_U32(pPayload, Para3);
- ENCODE_U32(pPayload, Para4);
- ENCODE_U32(pPayload, Para5);
- ENCODE_U32(pPayload, Para6);
- ENCODE_U32(pPayload, Para7);
- ENCODE_U32(pPayload, Para8);
- ENCODE_U32(pPayload, Para9);
- _SendPacket(pPayloadStart, pPayload, EventID);
- RECORD_END();
-}
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordString()
-*
-* Function description
-* Formats and sends a SystemView packet containing a string.
-*
-* Parameters
-* EventID - SystemView event ID.
-* pString - The string to be sent in the SystemView packet payload.
-*
-* Additional information
-* The string is encoded as a count byte followed by the contents
-* of the string.
-* No more than SEGGER_SYSVIEW_MAX_STRING_LEN bytes will be encoded to the payload.
-*/
-void SEGGER_SYSVIEW_RecordString(unsigned int EventID, const char* pString) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
- //
- pPayload = _EncodeStr(pPayloadStart, pString, SEGGER_SYSVIEW_MAX_STRING_LEN);
- _SendPacket(pPayloadStart, pPayload, EventID);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_Start()
-*
-* Function description
-* Start recording SystemView events.
-* This function is triggered by the host application.
-*
-* Additional information
-* This function enables transmission of SystemView packets recorded
-* by subsequent trace calls and records a SystemView Start event.
-*
-* As part of start, a SystemView Init packet is sent, containing the system
-* frequency. The list of current tasks, the current system time and the
-* system description string is sent, too.
-*
-* Notes
-* SEGGER_SYSVIEW_Start and SEGGER_SYSVIEW_Stop do not nest.
-*/
-void SEGGER_SYSVIEW_Start(void) {
- if (_SYSVIEW_Globals.EnableState == 0) {
- _SYSVIEW_Globals.EnableState = 1;
-#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
- _SendSyncInfo();
-#else
- SEGGER_SYSVIEW_LOCK();
- SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, _abSync, 10);
- SEGGER_SYSVIEW_UNLOCK();
- SEGGER_SYSVIEW_RecordVoid(SYSVIEW_EVTID_TRACE_START);
- {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, _SYSVIEW_Globals.SysFreq);
- ENCODE_U32(pPayload, _SYSVIEW_Globals.CPUFreq);
- ENCODE_U32(pPayload, _SYSVIEW_Globals.RAMBaseAddress);
- ENCODE_U32(pPayload, SEGGER_SYSVIEW_ID_SHIFT);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_INIT);
- RECORD_END();
- }
- if (_SYSVIEW_Globals.pfSendSysDesc) {
- _SYSVIEW_Globals.pfSendSysDesc();
- }
- SEGGER_SYSVIEW_RecordSystime();
- SEGGER_SYSVIEW_SendTaskList();
- SEGGER_SYSVIEW_SendNumModules();
-#endif
- }
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_Stop()
-*
-* Function description
-* Stop recording SystemView events.
-*
-* Additional information
-* This function disables transmission of SystemView packets recorded
-* by subsequent trace calls. If transmission is enabled when
-* this function is called, a single SystemView Stop event is recorded
-* to the trace, send, and then trace transmission is halted.
-*/
-void SEGGER_SYSVIEW_Stop(void) {
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
- //
- if (_SYSVIEW_Globals.EnableState) {
- _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_TRACE_STOP);
- _SYSVIEW_Globals.EnableState = 0;
- }
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_GetSysDesc()
-*
-* Function description
-* Triggers a send of the system information and description.
-*
-*/
-void SEGGER_SYSVIEW_GetSysDesc(void) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, _SYSVIEW_Globals.SysFreq);
- ENCODE_U32(pPayload, _SYSVIEW_Globals.CPUFreq);
- ENCODE_U32(pPayload, _SYSVIEW_Globals.RAMBaseAddress);
- ENCODE_U32(pPayload, SEGGER_SYSVIEW_ID_SHIFT);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_INIT);
- RECORD_END();
- if (_SYSVIEW_Globals.pfSendSysDesc) {
- _SYSVIEW_Globals.pfSendSysDesc();
- }
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_SendTaskInfo()
-*
-* Function description
-* Send a Task Info Packet, containing TaskId for identification,
-* task priority and task name.
-*
-* Parameters
-* pInfo - Pointer to task information to send.
-*/
-void SEGGER_SYSVIEW_SendTaskInfo(const SEGGER_SYSVIEW_TASKINFO *pInfo) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32 + 1 + 32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, SHRINK_ID(pInfo->TaskID));
- ENCODE_U32(pPayload, pInfo->Prio);
- pPayload = _EncodeStr(pPayload, pInfo->sName, 32);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_INFO);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, SHRINK_ID(pInfo->TaskID));
- ENCODE_U32(pPayload, pInfo->StackBase);
- ENCODE_U32(pPayload, pInfo->StackSize);
- ENCODE_U32(pPayload, 0); // Stack End, future use
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_STACK_INFO);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_SendTaskList()
-*
-* Function description
-* Send all tasks descriptors to the host.
-*/
-void SEGGER_SYSVIEW_SendTaskList(void) {
- if (_SYSVIEW_Globals.pOSAPI && _SYSVIEW_Globals.pOSAPI->pfSendTaskList) {
- _SYSVIEW_Globals.pOSAPI->pfSendTaskList();
- }
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_SendSysDesc()
-*
-* Function description
-* Send the system description string to the host.
-* The system description is used by SystemViewer to identify the
-* current application and handle events accordingly.
-*
-* Parameters
-* sSysDesc - Pointer to the 0-terminated system description string.
-*
-* Additional information
-* One system description string may not exceed SEGGER_SYSVIEW_MAX_STRING_LEN characters.
-*
-* The Following items can be described in a system description string.
-* Each item is identified by its identifier, followed by '=' and the value.
-* Items are separated by ','.
-*/
-void SEGGER_SYSVIEW_SendSysDesc(const char *sSysDesc) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
- //
- pPayload = _EncodeStr(pPayloadStart, sSysDesc, SEGGER_SYSVIEW_MAX_STRING_LEN);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_SYSDESC);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordSystime()
-*
-* Function description
-* Formats and sends a SystemView Systime containing a single U64 or U32
-* parameter payload.
-*/
-void SEGGER_SYSVIEW_RecordSystime(void) {
- U64 Systime;
-
- if (_SYSVIEW_Globals.pOSAPI && _SYSVIEW_Globals.pOSAPI->pfGetTime) {
- Systime = _SYSVIEW_Globals.pOSAPI->pfGetTime();
- SEGGER_SYSVIEW_RecordU32x2(SYSVIEW_EVTID_SYSTIME_US,
- (U32)(Systime),
- (U32)(Systime >> 32));
- } else {
- SEGGER_SYSVIEW_RecordU32(SYSVIEW_EVTID_SYSTIME_CYCLES, SEGGER_SYSVIEW_GET_TIMESTAMP());
- }
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordEnterISR()
-*
-* Function description
-* Format and send an ISR entry event.
-*
-* Additional information
-* Example packets sent
-* 02 0F 50 // ISR(15) Enter. Timestamp is 80 (0x50)
-*/
-void SEGGER_SYSVIEW_RecordEnterISR(U32 IrqId) {
- unsigned v;
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- v = IrqId;//SEGGER_SYSVIEW_GET_INTERRUPT_ID();
- ENCODE_U32(pPayload, v);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_ISR_ENTER);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordExitISR()
-*
-* Function description
-* Format and send an ISR exit event.
-*
-* Additional information
-* Format as follows:
-* 03 // Max. packet len is 6
-*
-* Example packets sent
-* 03 20 // ISR Exit. Timestamp is 32 (0x20)
-*/
-void SEGGER_SYSVIEW_RecordExitISR(void) {
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
- //
- _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_ISR_EXIT);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordExitISRToScheduler()
-*
-* Function description
-* Format and send an ISR exit into scheduler event.
-*
-* Additional information
-* Format as follows:
-* 18 // Max. packet len is 6
-*
-* Example packets sent
-* 18 20 // ISR Exit to Scheduler. Timestamp is 32 (0x20)
-*/
-void SEGGER_SYSVIEW_RecordExitISRToScheduler(void) {
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
- //
- _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_ISR_TO_SCHEDULER);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordEnterTimer()
-*
-* Function description
-* Format and send a Timer entry event.
-*
-* Parameters
-* TimerId - Id of the timer which starts.
-*/
-void SEGGER_SYSVIEW_RecordEnterTimer(U32 TimerId) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, SHRINK_ID(TimerId));
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TIMER_ENTER);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordExitTimer()
-*
-* Function description
-* Format and send a Timer exit event.
-*/
-void SEGGER_SYSVIEW_RecordExitTimer(void) {
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
- //
- _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_TIMER_EXIT);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordEndCall()
-*
-* Function description
-* Format and send an End API Call event without return value.
-*
-* Parameters
-* EventID - Id of API function which ends.
-*/
-void SEGGER_SYSVIEW_RecordEndCall(unsigned int EventID) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, EventID);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_END_CALL);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordEndCallU32()
-*
-* Function description
-* Format and send an End API Call event with return value.
-*
-* Parameters
-* EventID - Id of API function which ends.
-* Para0 - Return value which will be returned by the API function.
-*/
-void SEGGER_SYSVIEW_RecordEndCallU32(unsigned int EventID, U32 Para0) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, EventID);
- ENCODE_U32(pPayload, Para0);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_END_CALL);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_OnIdle()
-*
-* Function description
-* Record an Idle event.
-*/
-void SEGGER_SYSVIEW_OnIdle(void) {
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
- //
- _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_IDLE);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_OnTaskCreate()
-*
-* Function description
-* Record a Task Create event. The Task Create event corresponds
-* to creating a task in the OS.
-*
-* Parameters
-* TaskId - Task ID of created task.
-*/
-void SEGGER_SYSVIEW_OnTaskCreate(U32 TaskId) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- TaskId = SHRINK_ID(TaskId);
- ENCODE_U32(pPayload, TaskId);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_CREATE);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_OnTaskTerminate()
-*
-* Function description
-* Record a Task termination event.
-* The Task termination event corresponds to terminating a task in
-* the OS. If the TaskId is the currently active task,
-* SEGGER_SYSVIEW_OnTaskStopExec may be used, either.
-*
-* Parameters
-* TaskId - Task ID of terminated task.
-*/
-void SEGGER_SYSVIEW_OnTaskTerminate(U32 TaskId) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- TaskId = SHRINK_ID(TaskId);
- ENCODE_U32(pPayload, TaskId);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_TERMINATE);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_OnTaskStartExec()
-*
-* Function description
-* Record a Task Start Execution event. The Task Start event
-* corresponds to when a task has started to execute rather than
-* when it is ready to execute.
-*
-* Parameters
-* TaskId - Task ID of task that started to execute.
-*/
-void SEGGER_SYSVIEW_OnTaskStartExec(U32 TaskId) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- TaskId = SHRINK_ID(TaskId);
- ENCODE_U32(pPayload, TaskId);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_START_EXEC);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_OnTaskStopExec()
-*
-* Function description
-* Record a Task Stop Execution event. The Task Stop event
-* corresponds to when a task stops executing and terminates.
-*/
-void SEGGER_SYSVIEW_OnTaskStopExec(void) {
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
- //
- _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_TASK_STOP_EXEC);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_OnTaskStartReady()
-*
-* Function description
-* Record a Task Start Ready event.
-*
-* Parameters
-* TaskId - Task ID of task that started to execute.
-*/
-void SEGGER_SYSVIEW_OnTaskStartReady(U32 TaskId) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- TaskId = SHRINK_ID(TaskId);
- ENCODE_U32(pPayload, TaskId);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_START_READY);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_OnTaskStopReady()
-*
-* Function description
-* Record a Task Stop Ready event.
-*
-* Parameters
-* TaskId - Task ID of task that completed execution.
-* Cause - Reason for task to stop (i.e. Idle/Sleep)
-*/
-void SEGGER_SYSVIEW_OnTaskStopReady(U32 TaskId, unsigned int Cause) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- TaskId = SHRINK_ID(TaskId);
- ENCODE_U32(pPayload, TaskId);
- ENCODE_U32(pPayload, Cause);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_STOP_READY);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_OnUserStart()
-*
-* Function description
-* Send a user event start, such as start of a subroutine for profiling.
-*
-* Parameters
-* UserId - User defined ID for the event.
-*/
-void SEGGER_SYSVIEW_OnUserStart(unsigned UserId) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, UserId);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_USER_START);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_OnUserStop()
-*
-* Function description
-* Send a user event stop, such as return of a subroutine for profiling.
-*
-* Parameters
-* UserId - User defined ID for the event.
-*/
-void SEGGER_SYSVIEW_OnUserStop(unsigned UserId) {
- U8 * pPayload;
- U8 * pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, UserId);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_USER_STOP);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_NameResource()
-*
-* Function description
-* Send the name of a resource to be displayed in SystemViewer.
-*
-* Parameters
-* ResourceId - Id of the resource to be named. i.e. its address.
-* sName - Pointer to the resource name. (Max. SEGGER_SYSVIEW_MAX_STRING_LEN Bytes)
-*/
-void SEGGER_SYSVIEW_NameResource(U32 ResourceId, const char* sName) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
- //
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, SHRINK_ID(ResourceId));
- pPayload = _EncodeStr(pPayload, sName, SEGGER_SYSVIEW_MAX_STRING_LEN);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_NAME_RESOURCE);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_SendPacket()
-*
-* Function description
-* Send an event packet.
-*
-* Parameters
-* pPacket - Pointer to the start of the packet.
-* pPayloadEnd - Pointer to the end of the payload.
-* Make sure there are at least 5 bytes free after the payload.
-* EventId - Id of the event packet.
-*
-* Return value
-* !=0: Success, Message sent.
-* ==0: Buffer full, Message *NOT* sent.
-*/
-int SEGGER_SYSVIEW_SendPacket(U8* pPacket, U8* pPayloadEnd, unsigned int EventId) {
-#if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1)
- SEGGER_SYSVIEW_LOCK();
-#endif
- _SendPacket(pPacket + 4, pPayloadEnd, EventId);
-#if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1)
- SEGGER_SYSVIEW_UNLOCK();
-#endif
- return 0;
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_EncodeU32()
-*
-* Function description
-* Encode a U32 in variable-length format.
-*
-* Parameters
-* pPayload - Pointer to where U32 will be encoded.
-* Value - The 32-bit value to be encoded.
-*
-* Return value
-* Pointer to the byte following the value, i.e. the first free
-* byte in the payload and the next position to store payload
-* content.
-*/
-U8* SEGGER_SYSVIEW_EncodeU32(U8* pPayload, U32 Value) {
- ENCODE_U32(pPayload, Value);
- return pPayload;
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_EncodeString()
-*
-* Function description
-* Encode a string in variable-length format.
-*
-* Parameters
-* pPayload - Pointer to where string will be encoded.
-* s - String to encode.
-* MaxLen - Maximum number of characters to encode from string.
-*
-* Return value
-* Pointer to the byte following the value, i.e. the first free
-* byte in the payload and the next position to store payload
-* content.
-*
-* Additional information
-* The string is encoded as a count byte followed by the contents
-* of the string.
-* No more than 1 + MaxLen bytes will be encoded to the payload.
-*/
-U8* SEGGER_SYSVIEW_EncodeString(U8* pPayload, const char* s, unsigned int MaxLen) {
- return _EncodeStr(pPayload, s, MaxLen);
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_EncodeData()
-*
-* Function description
-* Encode a byte buffer in variable-length format.
-*
-* Parameters
-* pPayload - Pointer to where string will be encoded.
-* pSrc - Pointer to data buffer to be encoded.
-* NumBytes - Number of bytes in the buffer to be encoded.
-*
-* Return value
-* Pointer to the byte following the value, i.e. the first free
-* byte in the payload and the next position to store payload
-* content.
-*
-* Additional information
-* The data is encoded as a count byte followed by the contents
-* of the data buffer.
-* Make sure NumBytes + 1 bytes are free for the payload.
-*/
-U8* SEGGER_SYSVIEW_EncodeData(U8 *pPayload, const char* pSrc, unsigned int NumBytes) {
- return _EncodeData(pPayload, pSrc, NumBytes);
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_EncodeId()
-*
-* Function description
-* Encode a 32-bit Id in shrunken variable-length format.
-*
-* Parameters
-* pPayload - Pointer to where the Id will be encoded.
-* Id - The 32-bit value to be encoded.
-*
-* Return value
-* Pointer to the byte following the value, i.e. the first free
-* byte in the payload and the next position to store payload
-* content.
-*
-* Additional information
-* The parameters to shrink an Id can be configured in
-* SEGGER_SYSVIEW_Conf.h and via SEGGER_SYSVIEW_SetRAMBase().
-* SEGGER_SYSVIEW_ID_BASE: Lowest Id reported by the application.
-* (i.e. 0x20000000 when all Ids are an address in this RAM)
-* SEGGER_SYSVIEW_ID_SHIFT: Number of bits to shift the Id to
-* save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
-*/
-U8* SEGGER_SYSVIEW_EncodeId(U8* pPayload, U32 Id) {
- Id = SHRINK_ID(Id);
- ENCODE_U32(pPayload, Id);
- return pPayload;
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_ShrinkId()
-*
-* Function description
-* Get the shrunken value of an Id for further processing like in
-* SEGGER_SYSVIEW_NameResource().
-*
-* Parameters
-* Id - The 32-bit value to be shrunken.
-*
-* Return value
-* Shrunken Id.
-*
-* Additional information
-* The parameters to shrink an Id can be configured in
-* SEGGER_SYSVIEW_Conf.h and via SEGGER_SYSVIEW_SetRAMBase().
-* SEGGER_SYSVIEW_ID_BASE: Lowest Id reported by the application.
-* (i.e. 0x20000000 when all Ids are an address in this RAM)
-* SEGGER_SYSVIEW_ID_SHIFT: Number of bits to shift the Id to
-* save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
-*/
-U32 SEGGER_SYSVIEW_ShrinkId(U32 Id) {
- return SHRINK_ID(Id);
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RegisterModule()
-*
-* Function description
-* Register a middleware module for recording its events.
-*
-* Parameters
-* pModule - The middleware module information.
-*
-* Additional information
-* SEGGER_SYSVIEW_MODULE elements:
-* sDescription - Pointer to a string containing the module name and optionally the module event description.
-* NumEvents - Number of events the module wants to register.
-* EventOffset - Offset to be added to the event Ids. Out parameter, set by this function. Do not modify after calling this function.
-* pfSendModuleDesc - Callback function pointer to send more detailed module description to SystemViewer.
-* pNext - Pointer to next registered module. Out parameter, set by this function. Do not modify after calling this function.
-*/
-void SEGGER_SYSVIEW_RegisterModule(SEGGER_SYSVIEW_MODULE* pModule) {
- SEGGER_SYSVIEW_LOCK();
- if (_pFirstModule == 0) {
- //
- // No module registered, yet.
- // Start list with new module.
- // EventOffset is the base offset for modules
- //
- pModule->EventOffset = MODULE_EVENT_OFFSET;
- pModule->pNext = 0;
- _pFirstModule = pModule;
- _NumModules = 1;
- } else {
- //
- // Registreded module(s) present.
- // Prepend new module in list.
- // EventOffset set from number of events and offset of previous module.
- //
- pModule->EventOffset = _pFirstModule->EventOffset + _pFirstModule->NumEvents;
- pModule->pNext = _pFirstModule;
- _pFirstModule = pModule;
- _NumModules++;
- }
- SEGGER_SYSVIEW_SendModule(0);
- if (pModule->pfSendModuleDesc) {
- pModule->pfSendModuleDesc();
- }
- SEGGER_SYSVIEW_UNLOCK();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_RecordModuleDescription()
-*
-* Function description
-* Sends detailed information of a registered module to the host.
-*
-* Parameters
-* pModule - Pointer to the described module.
-* sDescription - Pointer to a description string.
-*/
-void SEGGER_SYSVIEW_RecordModuleDescription(const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription) {
- U8 ModuleId;
- SEGGER_SYSVIEW_MODULE* p;
-
- p = _pFirstModule;
- ModuleId = 0;
- do {
- if (p == pModule) {
- break;
- }
- ModuleId++;
- p = p->pNext;
- } while (p);
- {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
- //
- pPayload = pPayloadStart;
- //
- // Send module description
- // Send event offset and number of events
- //
- ENCODE_U32(pPayload, ModuleId);
- ENCODE_U32(pPayload, (pModule->EventOffset));
- pPayload = _EncodeStr(pPayload, sDescription, SEGGER_SYSVIEW_MAX_STRING_LEN);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MODULEDESC);
- RECORD_END();
- }
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_SendModule()
-*
-* Function description
-* Sends the information of a registered module to the host.
-*
-* Parameters
-* ModuleId - Id of the requested module.
-*/
-void SEGGER_SYSVIEW_SendModule(U8 ModuleId) {
- SEGGER_SYSVIEW_MODULE* pModule;
- U32 n;
-
- if (_pFirstModule != 0) {
- pModule = _pFirstModule;
- for (n = 0; n < ModuleId; n++) {
- pModule = pModule->pNext;
- if (pModule == 0) {
- break;
- }
- }
- if (pModule != 0) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
- //
- pPayload = pPayloadStart;
- //
- // Send module description
- // Send event offset and number of events
- //
- ENCODE_U32(pPayload, ModuleId);
- ENCODE_U32(pPayload, (pModule->EventOffset));
- pPayload = _EncodeStr(pPayload, pModule->sModule, SEGGER_SYSVIEW_MAX_STRING_LEN);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MODULEDESC);
- RECORD_END();
- }
- }
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_SendModuleDescription()
-*
-* Function description
-* Triggers a send of the registered module descriptions.
-*
-*/
-void SEGGER_SYSVIEW_SendModuleDescription(void) {
- SEGGER_SYSVIEW_MODULE* pModule;
-
- if (_pFirstModule != 0) {
- pModule = _pFirstModule;
- do {
- if (pModule->pfSendModuleDesc) {
- pModule->pfSendModuleDesc();
- }
- pModule = pModule->pNext;
- } while (pModule);
- }
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_SendNumModules()
-*
-* Function description
-* Send the number of registered modules to the host.
-*/
-void SEGGER_SYSVIEW_SendNumModules(void) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2*SEGGER_SYSVIEW_QUANTA_U32);
- pPayload = pPayloadStart;
- ENCODE_U32(pPayload, _NumModules);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_NUMMODULES);
- RECORD_END();
-}
-
-#ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_PrintfHostEx()
-*
-* Function description
-* Print a string which is formatted on the host by SystemViewer
-* with Additional information.
-*
-* Parameters
-* s - String to be formatted.
-* Options - Options for the string. i.e. Log level.
-*
-* Additional information
-* All format arguments are treated as 32-bit scalar values.
-*/
-void SEGGER_SYSVIEW_PrintfHostEx(const char* s, U32 Options, ...) {
- va_list ParamList;
-
- va_start(ParamList, Options);
- _VPrintHost(s, Options, &ParamList);
- va_end(ParamList);
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_PrintfHost()
-*
-* Function description
-* Print a string which is formatted on the host by SystemViewer.
-*
-* Parameters
-* s - String to be formatted.
-*
-* Additional information
-* All format arguments are treated as 32-bit scalar values.
-*/
-void SEGGER_SYSVIEW_PrintfHost(const char* s, ...) {
- va_list ParamList;
-
- va_start(ParamList, s);
- _VPrintHost(s, SEGGER_SYSVIEW_LOG, &ParamList);
- va_end(ParamList);
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_WarnfHost()
-*
-* Function description
-* Print a warnin string which is formatted on the host by
-* SystemViewer.
-*
-* Parameters
-* s - String to be formatted.
-*
-* Additional information
-* All format arguments are treated as 32-bit scalar values.
-*/
-void SEGGER_SYSVIEW_WarnfHost(const char* s, ...) {
- va_list ParamList;
-
- va_start(ParamList, s);
- _VPrintHost(s, SEGGER_SYSVIEW_WARNING, &ParamList);
- va_end(ParamList);
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_ErrorfHost()
-*
-* Function description
-* Print an error string which is formatted on the host by
-* SystemViewer.
-*
-* Parameters
-* s - String to be formatted.
-*
-* Additional information
-* All format arguments are treated as 32-bit scalar values.
-*/
-void SEGGER_SYSVIEW_ErrorfHost(const char* s, ...) {
- va_list ParamList;
-
- va_start(ParamList, s);
- _VPrintHost(s, SEGGER_SYSVIEW_ERROR, &ParamList);
- va_end(ParamList);
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_PrintfTargetEx()
-*
-* Function description
-* Print a string which is formatted on the target before sent to
-* the host with Additional information.
-*
-* Parameters
-* s - String to be formatted.
-* Options - Options for the string. i.e. Log level.
-*/
-void SEGGER_SYSVIEW_PrintfTargetEx(const char* s, U32 Options, ...) {
- va_list ParamList;
-
- va_start(ParamList, Options);
- _VPrintTarget(s, Options, &ParamList);
- va_end(ParamList);
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_PrintfTarget()
-*
-* Function description
-* Print a string which is formatted on the target before sent to
-* the host.
-*
-* Parameters
-* s - String to be formatted.
-*/
-void SEGGER_SYSVIEW_PrintfTarget(const char* s, ...) {
- va_list ParamList;
-
- va_start(ParamList, s);
- _VPrintTarget(s, SEGGER_SYSVIEW_LOG, &ParamList);
- va_end(ParamList);
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_WarnfTarget()
-*
-* Function description
-* Print a warning string which is formatted on the target before
-* sent to the host.
-*
-* Parameters
-* s - String to be formatted.
-*/
-void SEGGER_SYSVIEW_WarnfTarget(const char* s, ...) {
- va_list ParamList;
-
- va_start(ParamList, s);
- _VPrintTarget(s, SEGGER_SYSVIEW_WARNING, &ParamList);
- va_end(ParamList);
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_ErrorfTarget()
-*
-* Function description
-* Print an error string which is formatted on the target before
-* sent to the host.
-*
-* Parameters
-* s - String to be formatted.
-*/
-void SEGGER_SYSVIEW_ErrorfTarget(const char* s, ...) {
- va_list ParamList;
-
- va_start(ParamList, s);
- _VPrintTarget(s, SEGGER_SYSVIEW_ERROR, &ParamList);
- va_end(ParamList);
-}
-#endif // SEGGER_SYSVIEW_EXCLUDE_PRINTF
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_Print()
-*
-* Function description
-* Print a string to the host.
-*
-* Parameters
-* s - String to sent.
-*/
-void SEGGER_SYSVIEW_Print(const char* s) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_STRING_LEN);
- //
- pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
- ENCODE_U32(pPayload, SEGGER_SYSVIEW_LOG);
- ENCODE_U32(pPayload, 0);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_Warn()
-*
-* Function description
-* Print a warning string to the host.
-*
-* Parameters
-* s - String to sent.
-*/
-void SEGGER_SYSVIEW_Warn(const char* s) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_STRING_LEN);
- //
- pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
- ENCODE_U32(pPayload, SEGGER_SYSVIEW_WARNING);
- ENCODE_U32(pPayload, 0);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_Error()
-*
-* Function description
-* Print an error string to the host.
-*
-* Parameters
-* s - String to sent.
-*/
-void SEGGER_SYSVIEW_Error(const char* s) {
- U8* pPayload;
- U8* pPayloadStart;
- RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_STRING_LEN);
- //
- pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
- ENCODE_U32(pPayload, SEGGER_SYSVIEW_ERROR);
- ENCODE_U32(pPayload, 0);
- _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
- RECORD_END();
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_EnableEvents()
-*
-* Function description
-* Enable standard SystemView events to be generated.
-*
-* Parameters
-* EnableMask - Events to be enabled.
-*/
-void SEGGER_SYSVIEW_EnableEvents(U32 EnableMask) {
- _SYSVIEW_Globals.DisabledEvents &= ~EnableMask;
-}
-
-/*********************************************************************
-*
-* SEGGER_SYSVIEW_DisableEvents()
-*
-* Function description
-* Disable standard SystemView events to not be generated.
-*
-* Parameters
-* DisableMask - Events to be disabled.
-*/
-void SEGGER_SYSVIEW_DisableEvents(U32 DisableMask) {
- _SYSVIEW_Globals.DisabledEvents |= DisableMask;
-}
-
-
-/*************************** End of file ****************************/
+/*********************************************************************
+* SEGGER Microcontroller GmbH & Co. KG *
+* The Embedded Experts *
+**********************************************************************
+* *
+* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
+* *
+* www.segger.com Support: support@segger.com *
+* *
+**********************************************************************
+* *
+* SEGGER SystemView * Real-time application analysis *
+* *
+**********************************************************************
+* *
+* All rights reserved. *
+* *
+* SEGGER strongly recommends to not make any changes *
+* to or modify the source code of this software in order to stay *
+* compatible with the RTT protocol and J-Link. *
+* *
+* Redistribution and use in source and binary forms, with or *
+* without modification, are permitted provided that the following *
+* conditions are met: *
+* *
+* o Redistributions of source code must retain the above copyright *
+* notice, this list of conditions and the following disclaimer. *
+* *
+* o Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the following *
+* disclaimer in the documentation and/or other materials provided *
+* with the distribution. *
+* *
+* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
+* nor the names of its contributors may be used to endorse or *
+* promote products derived from this software without specific *
+* prior written permission. *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
+* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
+* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
+* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
+* DAMAGE. *
+* *
+**********************************************************************
+* *
+* SystemView version: V2.42 *
+* *
+**********************************************************************
+-------------------------- END-OF-HEADER -----------------------------
+
+File : SEGGER_SYSVIEW.c
+Purpose : System visualization API implementation.
+Revision: $Rev: 5927 $
+
+Additional information:
+ Packet format:
+ Packets with IDs 0..23 are standard packets with known structure.
+ For efficiency, they do *NOT* contain a length field.
+
+
+ Packets with IDs 24..31 are standard packets with extendible
+ structure and contain a length field.
+
+
+ Packets with IDs >= 32 always contain a length field.
+
+
+ Packet IDs:
+ 0.. 31 : Standard packets, known by SystemViewer.
+ 32..1023 : OS-definable packets, described in a SystemView description file.
+ 1024..2047 : User-definable packets, described in a SystemView description file.
+ 2048..32767: Undefined.
+
+ Data encoding:
+ Basic types (int, short, char, ...):
+ Basic types are encoded little endian with most-significant bit variant
+ encoding.
+ Each encoded byte contains 7 data bits [6:0] and the MSB continuation bit.
+ The continuation bit indicates whether the next byte belongs to the data
+ (bit set) or this is the last byte (bit clear).
+ The most significant bits of data are encoded first, proceeding to the
+ least significant bits in the final byte (little endian).
+
+ Example encoding:
+ Data: 0x1F4 (500)
+ Encoded: 0xF4 (First 7 data bits 74 | Continuation bit)
+ 0x03 (Second 7 data bits 03, no continuation)
+
+ Data: 0xFFFFFFFF
+ Encoded: 0xFF 0xFF 0xFF 0xFF 0x0F
+
+ Data: 0xA2 (162), 0x03 (3), 0x7000
+ Encoded: 0xA2 0x01 0x03 0x80 0xE0 0x01
+
+ Byte arrays and strings:
+ Byte arrays and strings are encoded as followed by the raw data.
+ NumBytes is encoded as a basic type with a theoretical maximum of 4G.
+
+ Example encoding:
+ Data: "Hello World\0" (0x48 0x65 0x6C 0x6C 0x6F 0x20 0x57 0x6F 0x72 0x6C 0x64 0x00)
+ Encoded: 0x0B 0x48 0x65 0x6C 0x6C 0x6F 0x20 0x57 0x6F 0x72 0x6C 0x64
+
+ Examples packets:
+ 01 F4 03 80 80 10 // Overflow packet. Data is a single U32.
+ This packet means: 500 packets lost, Timestamp is 0x40000
+
+ 02 0F 50 // ISR(15) Enter. Timestamp 80 (0x50)
+
+ 03 20 // ISR Exit. Timestamp 32 (0x20) (Shortest possible packet.)
+
+ Sample code for user defined Packets:
+ #define MY_ID 0x400 // Any value between 0x400 and 0x7FF
+ void SendMyPacket(unsigned Para0, unsigned Para1, const char* s) {
+ U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + MAX_STR_LEN + 1];
+ U8* pPayload;
+ //
+ pPayload = SEGGER_SYSVIEW_PPREPARE_PACKET(aPacket); // Prepare the packet for SystemView
+ pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
+ pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
+ pPayload = SEGGER_SYSVIEW_EncodeString(pPayload, s, MAX_STR_LEN); // Add the string to the packet
+ //
+ SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, MY_ID); // Send the packet with EventId = MY_ID
+ }
+
+ #define MY_ID_1 0x401
+ void SendOnePara(unsigned Para0) {
+ SEGGER_SYSVIEW_RecordU32(MY_ID_1, Para0);
+ }
+
+*/
+
+/*********************************************************************
+*
+* #include section
+*
+**********************************************************************
+*/
+
+#include "SEGGER_SYSVIEW_Int.h"
+#include "SEGGER_RTT.h"
+#include
+#include
+#include
+
+/*********************************************************************
+*
+* Defines, fixed
+*
+**********************************************************************
+*/
+#if SEGGER_SYSVIEW_ID_SHIFT
+ #define SHRINK_ID(Id) (((Id) - _SYSVIEW_Globals.RAMBaseAddress) >> SEGGER_SYSVIEW_ID_SHIFT)
+#else
+ #define SHRINK_ID(Id) ((Id) - _SYSVIEW_Globals.RAMBaseAddress)
+#endif
+
+#if SEGGER_SYSVIEW_RTT_CHANNEL > 0
+ #define CHANNEL_ID_UP SEGGER_SYSVIEW_RTT_CHANNEL
+ #define CHANNEL_ID_DOWN SEGGER_SYSVIEW_RTT_CHANNEL
+#else
+ #define CHANNEL_ID_UP _SYSVIEW_Globals.UpChannel
+ #define CHANNEL_ID_DOWN _SYSVIEW_Globals.DownChannel
+#endif
+
+/*********************************************************************
+*
+* Defines, configurable
+*
+**********************************************************************
+*/
+// Timestamps may be less than full 32-bits, in which case we need to zero
+// the unused bits to properly handle overflows.
+// Note that this is a quite common scenario, as a 32-bit time such as
+// SysTick might be scaled down to reduce bandwith
+// or a 16-bit hardware time might be used.
+#if SEGGER_SYSVIEW_TIMESTAMP_BITS < 32 // Eliminate unused bits in case hardware timestamps are less than 32 bits
+ #define MAKE_DELTA_32BIT(Delta) Delta <<= 32 - SEGGER_SYSVIEW_TIMESTAMP_BITS; \
+ Delta >>= 32 - SEGGER_SYSVIEW_TIMESTAMP_BITS;
+#else
+ #define MAKE_DELTA_32BIT(Delta)
+#endif
+
+
+/*********************************************************************
+*
+* Defines, fixed
+*
+**********************************************************************
+*/
+#define ENABLE_STATE_OFF 0
+#define ENABLE_STATE_ON 1
+#define ENABLE_STATE_DROPPING 2
+
+#define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0)
+#define FORMAT_FLAG_PAD_ZERO (1u << 1)
+#define FORMAT_FLAG_PRINT_SIGN (1u << 2)
+#define FORMAT_FLAG_ALTERNATE (1u << 3)
+
+#define MODULE_EVENT_OFFSET (512)
+
+/*********************************************************************
+*
+* Types, local
+*
+**********************************************************************
+*/
+typedef struct {
+ U8* pBuffer;
+ U8* pPayload;
+ U8* pPayloadStart;
+ U32 Options;
+ unsigned Cnt;
+} SEGGER_SYSVIEW_PRINTF_DESC;
+
+typedef struct {
+ U8 EnableState; // 0: Disabled, 1: Enabled, (2: Dropping)
+ U8 UpChannel;
+ U8 RecursionCnt;
+ U32 SysFreq;
+ U32 CPUFreq;
+ U32 LastTxTimeStamp;
+ U32 RAMBaseAddress;
+#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
+ U32 PacketCount;
+#else
+ U32 DropCount;
+ U8 DownChannel;
+#endif
+ U32 DisabledEvents;
+ const SEGGER_SYSVIEW_OS_API* pOSAPI;
+ SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC* pfSendSysDesc;
+} SEGGER_SYSVIEW_GLOBALS;
+
+/*********************************************************************
+*
+* Function prototypes, required
+*
+**********************************************************************
+*/
+static void _SendPacket(U8* pStartPacket, U8* pEndPacket, unsigned int EventId);
+
+/*********************************************************************
+*
+* Static data
+*
+**********************************************************************
+*/
+static const U8 _abSync[10] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#ifdef SEGGER_SYSVIEW_SECTION
+ #if (defined __GNUC__)
+ __attribute__ ((section (SEGGER_SYSVIEW_SECTION))) static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
+ #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
+ __attribute__ ((section (SEGGER_SYSVIEW_SECTION))) static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms
+ #endif
+ #elif (defined __ICCARM__) || (defined __ICCRX__)
+ #pragma location=SEGGER_SYSVIEW_SECTION
+ static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
+ #pragma location=SEGGER_SYSVIEW_SECTION
+ static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms
+ #elif (defined __CC_ARM)
+ __attribute__ ((section (SEGGER_SYSVIEW_SECTION), zero_init)) static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
+ #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
+ __attribute__ ((section (SEGGER_SYSVIEW_SECTION), zero_init)) static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms
+ #endif
+ #else
+ static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
+ #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
+ static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms
+ #endif
+ #endif
+#else
+ static char _UpBuffer [SEGGER_SYSVIEW_RTT_BUFFER_SIZE];
+ #if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
+ static char _DownBuffer[8]; // Small, fixed-size buffer, for back-channel comms
+ #endif
+#endif
+
+static SEGGER_SYSVIEW_GLOBALS _SYSVIEW_Globals;
+
+static SEGGER_SYSVIEW_MODULE* _pFirstModule;
+static U8 _NumModules;
+
+/*********************************************************************
+*
+* Static code
+*
+**********************************************************************
+*/
+
+#define ENCODE_U32(pDest, Value) { \
+ U8* pSysviewPointer; \
+ U32 SysViewData; \
+ pSysviewPointer = pDest; \
+ SysViewData = Value; \
+ while(SysViewData > 0x7F) { \
+ *pSysviewPointer++ = (U8)(SysViewData | 0x80); \
+ SysViewData >>= 7; \
+ }; \
+ *pSysviewPointer++ = (U8)SysViewData; \
+ pDest = pSysviewPointer; \
+ };
+
+
+
+#if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1)
+static U8 _aPacket[SEGGER_SYSVIEW_MAX_PACKET_SIZE];
+
+#define RECORD_START(PacketSize) SEGGER_SYSVIEW_LOCK(); \
+ pPayloadStart = _PreparePacket(_aPacket);
+
+#define RECORD_END() SEGGER_SYSVIEW_UNLOCK()
+
+#else
+
+#define RECORD_START(PacketSize) U8 aPacket[(PacketSize)]; \
+ pPayloadStart = _PreparePacket(aPacket); \
+
+#define RECORD_END()
+
+#endif
+
+/*********************************************************************
+*
+* _EncodeData()
+*
+* Function description
+* Encode a byte buffer in variable-length format.
+*
+* Parameters
+* pPayload - Pointer to where string will be encoded.
+* pSrc - Pointer to data buffer to be encoded.
+* NumBytes - Number of bytes in the buffer to be encoded.
+*
+* Return value
+* Pointer to the byte following the value, i.e. the first free
+* byte in the payload and the next position to store payload
+* content.
+*
+* Additional information
+* The data is encoded as a count byte followed by the contents
+* of the data buffer.
+* Make sure NumBytes + 1 bytes are free for the payload.
+*/
+static U8* _EncodeData(U8* pPayload, const char* pSrc, unsigned int NumBytes) {
+ unsigned int n;
+ //
+ n = 0;
+ *pPayload++ = NumBytes;
+ while (n < NumBytes) {
+ *pPayload++ = *pSrc++;
+ n++;
+ }
+ return pPayload;
+}
+
+/*********************************************************************
+*
+* _EncodeStr()
+*
+* Function description
+* Encode a string in variable-length format.
+*
+* Parameters
+* pPayload - Pointer to where string will be encoded.
+* pText - String to encode.
+* Limit - Maximum number of characters to encode from string.
+*
+* Return value
+* Pointer to the byte following the value, i.e. the first free
+* byte in the payload and the next position to store payload
+* content.
+*
+* Additional information
+* The string is encoded as a count byte followed by the contents
+* of the string.
+* No more than 1 + Limit bytes will be encoded to the payload.
+*/
+static U8 *_EncodeStr(U8 *pPayload, const char *pText, unsigned int Limit) {
+ unsigned int n;
+ unsigned int Len;
+ //
+ // Compute string len
+ //
+ Len = 0;
+ while(*(pText + Len) != 0) {
+ Len++;
+ }
+ if (Len > Limit) {
+ Len = Limit;
+ }
+ //
+ // Write Len
+ //
+ if (Len < 255) {
+ *pPayload++ = Len;
+ } else {
+ *pPayload++ = 255;
+ *pPayload++ = (Len & 255);
+ *pPayload++ = ((Len >> 8) & 255);
+ }
+ //
+ // copy string
+ //
+ n = 0;
+ while (n < Len) {
+ *pPayload++ = *pText++;
+ n++;
+ }
+ return pPayload;
+}
+
+/*********************************************************************
+*
+* _PreparePacket()
+*
+* Function description
+* Prepare a SystemView event packet header.
+*
+* Parameters
+* pPacket - Pointer to start of packet to initialize.
+*
+* Return value
+* Pointer to first byte of packet payload.
+*
+* Additional information
+* The payload length and evnetId are not initialized.
+* PreparePacket only reserves space for them and they are
+* computed and filled in by the sending function.
+*/
+static U8* _PreparePacket(U8* pPacket) {
+ return pPacket + 4;
+}
+
+/*********************************************************************
+*
+* _HandleIncomingPacket()
+*
+* Function description
+* Read an incoming command from the down channel and process it.
+*
+* Additional information
+* This function is called each time after sending a packet.
+* Processing incoming packets is done asynchronous. SystemView might
+* already have sent event packets after the host has sent a command.
+*/
+#if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
+static void _HandleIncomingPacket(void) {
+ U8 Cmd;
+ int Status;
+ //
+ Status = SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1);
+ if (Status > 0) {
+ switch (Cmd) {
+ case SEGGER_SYSVIEW_COMMAND_ID_START:
+ SEGGER_SYSVIEW_Start();
+ break;
+ case SEGGER_SYSVIEW_COMMAND_ID_STOP:
+ SEGGER_SYSVIEW_Stop();
+ break;
+ case SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME:
+ SEGGER_SYSVIEW_RecordSystime();
+ break;
+ case SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST:
+ SEGGER_SYSVIEW_SendTaskList();
+ break;
+ case SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC:
+ SEGGER_SYSVIEW_GetSysDesc();
+ break;
+ case SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES:
+ SEGGER_SYSVIEW_SendNumModules();
+ break;
+ case SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC:
+ SEGGER_SYSVIEW_SendModuleDescription();
+ break;
+ case SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE:
+ Status = SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1);
+ if (Status > 0) {
+ SEGGER_SYSVIEW_SendModule(Cmd);
+ }
+ break;
+ default:
+ if (Cmd >= 128) { // Unknown extended command. Dummy read its parameter.
+ SEGGER_RTT_ReadNoLock(CHANNEL_ID_DOWN, &Cmd, 1);
+ }
+ break;
+ }
+ }
+}
+#endif // (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
+
+/*********************************************************************
+*
+* _TrySendOverflowPacket()
+*
+* Function description
+* Try to transmit an SystemView Overflow packet containing the
+* number of dropped packets.
+*
+* Additional information
+* Format as follows:
+* 01 Max. packet len is 1 + 5 + 5 = 11
+*
+* Example packets sent
+* 01 20 40
+*
+* Return value
+* !=0: Success, Message sent (stored in RTT-Buffer)
+* ==0: Buffer full, Message *NOT* stored
+*
+*/
+#if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
+static int _TrySendOverflowPacket(void) {
+ U32 TimeStamp;
+ I32 Delta;
+ int Status;
+ U8 aPacket[11];
+ U8* pPayload;
+
+ aPacket[0] = SYSVIEW_EVTID_OVERFLOW; // 1
+ pPayload = &aPacket[1];
+ ENCODE_U32(pPayload, _SYSVIEW_Globals.DropCount);
+ //
+ // Compute time stamp delta and append it to packet.
+ //
+ TimeStamp = SEGGER_SYSVIEW_GET_TIMESTAMP();
+ Delta = TimeStamp - _SYSVIEW_Globals.LastTxTimeStamp;
+ MAKE_DELTA_32BIT(Delta);
+ ENCODE_U32(pPayload, Delta);
+ //
+ // Try to store packet in RTT buffer and update time stamp when this was successful
+ //
+ Status = SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, aPacket, pPayload - aPacket);
+ if (Status) {
+ _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp;
+ _SYSVIEW_Globals.EnableState--; // EnableState has been 2, will be 1. Always.
+ } else {
+ _SYSVIEW_Globals.DropCount++;
+ }
+ //
+ return Status;
+}
+#endif // (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
+
+/*********************************************************************
+*
+* _SendSyncInfo()
+*
+* Function description
+* Send SystemView sync packet and system information in
+* post mortem mode.
+*
+* Additional information
+* Sync is 10 * 0x00 without timestamp
+*/
+#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
+static void _SendSyncInfo(void) {
+ //
+ // Add sync packet ( 10 * 0x00)
+ // Send system description
+ // Send system time
+ // Send task list
+ // Send module description
+ // Send module information
+ //
+ SEGGER_RTT_WriteWithOverwriteNoLock(CHANNEL_ID_UP, _abSync, 10);
+ SEGGER_SYSVIEW_RecordVoid(SYSVIEW_EVTID_TRACE_START);
+ {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, _SYSVIEW_Globals.SysFreq);
+ ENCODE_U32(pPayload, _SYSVIEW_Globals.CPUFreq);
+ ENCODE_U32(pPayload, _SYSVIEW_Globals.RAMBaseAddress);
+ ENCODE_U32(pPayload, SEGGER_SYSVIEW_ID_SHIFT);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_INIT);
+ RECORD_END();
+ }
+ if (_SYSVIEW_Globals.pfSendSysDesc) {
+ _SYSVIEW_Globals.pfSendSysDesc();
+ }
+ SEGGER_SYSVIEW_RecordSystime();
+ SEGGER_SYSVIEW_SendTaskList();
+ if (_NumModules > 0) {
+ SEGGER_SYSVIEW_SendNumModules();
+ for (int n = 0; n < _NumModules; n++) {
+ SEGGER_SYSVIEW_SendModule(n);
+ }
+ SEGGER_SYSVIEW_SendModuleDescription();
+ }
+}
+#endif // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
+
+/*********************************************************************
+*
+* _SendPacket()
+*
+* Function description
+* Send a SystemView packet over RTT. RTT channel and mode are
+* configured by macros when the SystemView component is initialized.
+* This function takes care of maintaining the packet drop count
+* and sending overflow packets when necessary.
+* The packet must be passed without Id and Length because this
+* function prepends it to the packet before transmission.
+*
+* Parameters
+* pStartPacket - Pointer to start of packet payload.
+* There must be at least 4 bytes free to prepend Id and Length.
+* pEndPacket - Pointer to end of packet payload.
+* EventId - Id of the event to send.
+*
+*/
+static void _SendPacket(U8* pStartPacket, U8* pEndPacket, unsigned int EventId) {
+ unsigned int NumBytes;
+ U32 TimeStamp;
+ U32 Delta;
+#if (SEGGER_SYSVIEW_POST_MORTEM_MODE != 1)
+ int Status;
+#endif
+
+#if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0)
+ SEGGER_SYSVIEW_LOCK();
+#endif
+
+#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
+ if (_SYSVIEW_Globals.EnableState == 0) {
+ goto SendDone;
+ }
+#else
+ if (_SYSVIEW_Globals.EnableState == 1) { // Enabled, no dropped packets remaining
+ goto Send;
+ }
+ if (_SYSVIEW_Globals.EnableState == 0) {
+ goto SendDone;
+ }
+ //
+ // Handle buffer full situations:
+ // Have packets been dropped before because buffer was full?
+ // In this case try to send and overflow packet.
+ //
+ if (_SYSVIEW_Globals.EnableState == 2) {
+ _TrySendOverflowPacket();
+ if (_SYSVIEW_Globals.EnableState != 1) {
+ goto SendDone;
+ }
+ }
+Send:
+#endif
+ //
+ // Check if event is disabled from being recorded.
+ //
+ if (EventId < 32) {
+ if (_SYSVIEW_Globals.DisabledEvents & ((U32)1u << EventId)) {
+ goto SendDone;
+ }
+ }
+ //
+ // Prepare actual packet.
+ // If it is a known packet, prepend eventId only,
+ // otherwise prepend packet length and eventId.
+ //
+ if (EventId < 24) {
+ *--pStartPacket = EventId;
+ } else {
+ NumBytes = pEndPacket - pStartPacket;
+ if (NumBytes > 127) {
+ *--pStartPacket = (NumBytes >> 7);
+ *--pStartPacket = NumBytes | 0x80;
+ } else {
+ *--pStartPacket = NumBytes;
+ }
+ if (EventId > 127) {
+ *--pStartPacket = (EventId >> 7);
+ *--pStartPacket = EventId | 0x80;
+ } else {
+ *--pStartPacket = EventId;
+ }
+ }
+ //
+ // Compute time stamp delta and append it to packet.
+ //
+ TimeStamp = SEGGER_SYSVIEW_GET_TIMESTAMP();
+ Delta = TimeStamp - _SYSVIEW_Globals.LastTxTimeStamp;
+ MAKE_DELTA_32BIT(Delta);
+ ENCODE_U32(pEndPacket, Delta);
+#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
+ //
+ // Store packet in RTT buffer by overwriting old data and update time stamp
+ //
+ SEGGER_RTT_WriteWithOverwriteNoLock(CHANNEL_ID_UP, pStartPacket, pEndPacket - pStartPacket);
+ _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp;
+#else
+ //
+ // Try to store packet in RTT buffer and update time stamp when this was successful
+ //
+ Status = SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, pStartPacket, pEndPacket - pStartPacket);
+ if (Status) {
+ _SYSVIEW_Globals.LastTxTimeStamp = TimeStamp;
+ } else {
+ _SYSVIEW_Globals.EnableState++; // EnableState has been 1, will be 2. Always.
+ }
+#endif
+
+#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
+ //
+ // Add sync and system information periodically if we are in post mortem mode
+ //
+ if (_SYSVIEW_Globals.RecursionCnt == 0) { // Avoid uncontrolled nesting. This way, this routine can call itself once, but no more often than that.
+ _SYSVIEW_Globals.RecursionCnt = 1;
+ if (_SYSVIEW_Globals.PacketCount++ & (1 << SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT)) {
+ _SendSyncInfo();
+ _SYSVIEW_Globals.PacketCount = 0;
+ }
+ _SYSVIEW_Globals.RecursionCnt = 0;
+ }
+SendDone:
+ ; // Avoid "label at end of compound statement" error when using static buffer
+#else
+SendDone:
+ //
+ // Check if host is sending data which needs to be processed.
+ // Note that since this code is called for every packet, it is very time critical, so we do
+ // only what is really needed here, which is checking if there is any data
+ //
+ if (SEGGER_RTT_HASDATA(CHANNEL_ID_DOWN)) {
+ if (_SYSVIEW_Globals.RecursionCnt == 0) { // Avoid uncontrolled nesting. This way, this routine can call itself once, but no more often than that.
+ _SYSVIEW_Globals.RecursionCnt = 1;
+ _HandleIncomingPacket();
+ _SYSVIEW_Globals.RecursionCnt = 0;
+ }
+ }
+#endif
+ //
+#if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0)
+ SEGGER_SYSVIEW_UNLOCK(); // We are done. Unlock and return
+#endif
+}
+
+#ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
+/*********************************************************************
+*
+* _APrintHost()
+*
+* Function description
+* Prepares a string and its parameters to be formatted on the host.
+*
+* Parameters
+* s Pointer to format string.
+* Options Options to be sent to the host.
+* pArguments Pointer to array of arguments for the format string.
+* NumArguments Number of arguments in the array.
+*/
+static void _APrintHost(const char* s, U32 Options, U32* pArguments, U32 NumArguments) {
+ U8* pPayload;
+ U8* pPayloadStart;
+
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32);
+ pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
+ ENCODE_U32(pPayload, Options);
+ ENCODE_U32(pPayload, NumArguments);
+ while (NumArguments--) {
+ ENCODE_U32(pPayload, (*pArguments++));
+ }
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* _VPrintHost()
+*
+* Function description
+* Prepares a string and its parameters to be formatted on the host.
+*
+* Parameters
+* s Pointer to format string.
+* Options Options to be sent to the host.
+* pParamList Pointer to the list of arguments for the format string.
+*/
+static void _VPrintHost(const char* s, U32 Options, va_list* pParamList) {
+ U32 aParas[SEGGER_SYSVIEW_MAX_ARGUMENTS];
+ U32 NumArguments;
+ const char* p;
+
+ p = s;
+ NumArguments = 0;
+ while (*p) {
+ if (*p == '%') {
+ aParas[NumArguments++] = va_arg(*pParamList, int);
+ if (NumArguments == SEGGER_SYSVIEW_MAX_ARGUMENTS) {
+ break;
+ }
+ }
+ p++;
+ }
+ _APrintHost(s, Options, aParas, NumArguments);
+}
+
+/*********************************************************************
+*
+* _StoreChar()
+*
+* Function description
+* Stores a character in the printf-buffer and sends the buffer when
+* it is filled.
+*
+* Parameters
+* p Pointer to the buffer description.
+* c Character to be printed.
+*/
+static void _StoreChar(SEGGER_SYSVIEW_PRINTF_DESC * p, char c) {
+ unsigned int Cnt;
+ U8* pPayload;
+ U32 Options;
+
+ Cnt = p->Cnt;
+ if ((Cnt + 1u) <= SEGGER_SYSVIEW_MAX_STRING_LEN) {
+ *(p->pPayload++) = c;
+ p->Cnt = Cnt + 1u;
+ }
+ //
+ // Write part of string, when the buffer is full
+ //
+ if (p->Cnt == SEGGER_SYSVIEW_MAX_STRING_LEN) {
+ *(p->pPayloadStart) = p->Cnt;
+ pPayload = p->pPayload;
+ Options = p->Options;
+ ENCODE_U32(pPayload, Options);
+ ENCODE_U32(pPayload, 0);
+ _SendPacket(p->pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
+ p->pPayloadStart = _PreparePacket(p->pBuffer);
+ p->pPayload = p->pPayloadStart + 1u;
+ p->Cnt = 0u;
+ }
+}
+
+/*********************************************************************
+*
+* _PrintUnsigned()
+*
+* Function description
+* Print an unsigned integer with the given formatting into the
+* formatted string.
+*
+* Parameters
+* pBufferDesc Pointer to the buffer description.
+* v Value to be printed.
+* Base Base of the value.
+* NumDigits Number of digits to be printed.
+* FieldWidth Width of the printed field.
+* FormatFlags Flags for formatting the value.
+*/
+static void _PrintUnsigned(SEGGER_SYSVIEW_PRINTF_DESC * pBufferDesc, unsigned int v, unsigned int Base, unsigned int NumDigits, unsigned int FieldWidth, unsigned int FormatFlags) {
+ static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ unsigned int Div;
+ unsigned int Digit;
+ unsigned int Number;
+ unsigned int Width;
+ char c;
+
+ Number = v;
+ Digit = 1u;
+ //
+ // Get actual field width
+ //
+ Width = 1u;
+ while (Number >= Base) {
+ Number = (Number / Base);
+ Width++;
+ }
+ if (NumDigits > Width) {
+ Width = NumDigits;
+ }
+ //
+ // Print leading chars if necessary
+ //
+ if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
+ if (FieldWidth != 0u) {
+ if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
+ c = '0';
+ } else {
+ c = ' ';
+ }
+ while ((FieldWidth != 0u) && (Width < FieldWidth)) {
+ FieldWidth--;
+ _StoreChar(pBufferDesc, c);
+ }
+ }
+ }
+ //
+ // Compute Digit.
+ // Loop until Digit has the value of the highest digit required.
+ // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100.
+ //
+ while (1) {
+ if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned)
+ NumDigits--;
+ } else {
+ Div = v / Digit;
+ if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done
+ break;
+ }
+ }
+ Digit *= Base;
+ }
+ //
+ // Output digits
+ //
+ do {
+ Div = v / Digit;
+ v -= Div * Digit;
+ _StoreChar(pBufferDesc, _aV2C[Div]);
+ Digit /= Base;
+ } while (Digit);
+ //
+ // Print trailing spaces if necessary
+ //
+ if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
+ if (FieldWidth != 0u) {
+ while ((FieldWidth != 0u) && (Width < FieldWidth)) {
+ FieldWidth--;
+ _StoreChar(pBufferDesc, ' ');
+ }
+ }
+ }
+}
+
+/*********************************************************************
+*
+* _PrintInt()
+*
+* Function description
+* Print a signed integer with the given formatting into the
+* formatted string.
+*
+* Parameters
+* pBufferDesc Pointer to the buffer description.
+* v Value to be printed.
+* Base Base of the value.
+* NumDigits Number of digits to be printed.
+* FieldWidth Width of the printed field.
+* FormatFlags Flags for formatting the value.
+*/
+static void _PrintInt(SEGGER_SYSVIEW_PRINTF_DESC * pBufferDesc, int v, unsigned int Base, unsigned int NumDigits, unsigned int FieldWidth, unsigned int FormatFlags) {
+ unsigned int Width;
+ int Number;
+
+ Number = (v < 0) ? -v : v;
+
+ //
+ // Get actual field width
+ //
+ Width = 1u;
+ while (Number >= (int)Base) {
+ Number = (Number / (int)Base);
+ Width++;
+ }
+ if (NumDigits > Width) {
+ Width = NumDigits;
+ }
+ if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
+ FieldWidth--;
+ }
+
+ //
+ // Print leading spaces if necessary
+ //
+ if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
+ if (FieldWidth != 0u) {
+ while ((FieldWidth != 0u) && (Width < FieldWidth)) {
+ FieldWidth--;
+ _StoreChar(pBufferDesc, ' ');
+ }
+ }
+ }
+ //
+ // Print sign if necessary
+ //
+ if (v < 0) {
+ v = -v;
+ _StoreChar(pBufferDesc, '-');
+ } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
+ _StoreChar(pBufferDesc, '+');
+ } else {
+
+ }
+ //
+ // Print leading zeros if necessary
+ //
+ if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
+ if (FieldWidth != 0u) {
+ while ((FieldWidth != 0u) && (Width < FieldWidth)) {
+ FieldWidth--;
+ _StoreChar(pBufferDesc, '0');
+ }
+ }
+ }
+ //
+ // Print number without sign
+ //
+ _PrintUnsigned(pBufferDesc, (unsigned int)v, Base, NumDigits, FieldWidth, FormatFlags);
+}
+
+/*********************************************************************
+*
+* _VPrintTarget()
+*
+* Function description
+* Stores a formatted string.
+* This data is read by the host.
+*
+* Parameters
+* sFormat Pointer to format string.
+* Options Options to be sent to the host.
+* pParamList Pointer to the list of arguments for the format string.
+*/
+static void _VPrintTarget(const char* sFormat, U32 Options, va_list* pParamList) {
+ SEGGER_SYSVIEW_PRINTF_DESC BufferDesc;
+ char c;
+ int v;
+ unsigned int NumDigits;
+ unsigned int FormatFlags;
+ unsigned int FieldWidth;
+ U8* pPayloadStart;
+#if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 1 + 2 * SEGGER_SYSVIEW_QUANTA_U32);
+ SEGGER_SYSVIEW_LOCK();
+#else
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 1 + 2 * SEGGER_SYSVIEW_QUANTA_U32);
+#endif
+
+#if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0
+ BufferDesc.pBuffer = aPacket;
+#else
+ BufferDesc.pBuffer = _aPacket;
+#endif
+ BufferDesc.Cnt = 0u;
+ BufferDesc.pPayloadStart = pPayloadStart;
+ BufferDesc.pPayload = BufferDesc.pPayloadStart + 1u;
+ BufferDesc.Options = Options;
+
+ do {
+ c = *sFormat;
+ sFormat++;
+ if (c == 0u) {
+ break;
+ }
+ if (c == '%') {
+ //
+ // Filter out flags
+ //
+ FormatFlags = 0u;
+ v = 1;
+ do {
+ c = *sFormat;
+ switch (c) {
+ case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
+ case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break;
+ case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break;
+ case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break;
+ default: v = 0; break;
+ }
+ } while (v);
+ //
+ // filter out field with
+ //
+ FieldWidth = 0u;
+ do {
+ c = *sFormat;
+ if ((c < '0') || (c > '9')) {
+ break;
+ }
+ sFormat++;
+ FieldWidth = (FieldWidth * 10u) + ((unsigned int)c - '0');
+ } while (1);
+
+ //
+ // Filter out precision (number of digits to display)
+ //
+ NumDigits = 0u;
+ c = *sFormat;
+ if (c == '.') {
+ sFormat++;
+ do {
+ c = *sFormat;
+ if ((c < '0') || (c > '9')) {
+ break;
+ }
+ sFormat++;
+ NumDigits = NumDigits * 10u + ((unsigned int)c - '0');
+ } while (1);
+ }
+ //
+ // Filter out length modifier
+ //
+ c = *sFormat;
+ do {
+ if ((c == 'l') || (c == 'h')) {
+ c = *sFormat;
+ sFormat++;
+ } else {
+ break;
+ }
+ } while (1);
+ //
+ // Handle specifiers
+ //
+ switch (c) {
+ case 'c': {
+ char c0;
+ v = va_arg(*pParamList, int);
+ c0 = (char)v;
+ _StoreChar(&BufferDesc, c0);
+ break;
+ }
+ case 'd':
+ v = va_arg(*pParamList, int);
+ _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
+ break;
+ case 'u':
+ v = va_arg(*pParamList, int);
+ _PrintUnsigned(&BufferDesc, (unsigned int)v, 10u, NumDigits, FieldWidth, FormatFlags);
+ break;
+ case 'x':
+ case 'X':
+ v = va_arg(*pParamList, int);
+ _PrintUnsigned(&BufferDesc, (unsigned int)v, 16u, NumDigits, FieldWidth, FormatFlags);
+ break;
+ case 'p':
+ v = va_arg(*pParamList, int);
+ _PrintUnsigned(&BufferDesc, (unsigned int)v, 16u, 8u, 8u, 0u);
+ break;
+ case '%':
+ _StoreChar(&BufferDesc, '%');
+ break;
+ default:
+ break;
+ }
+ sFormat++;
+ } else {
+ _StoreChar(&BufferDesc, c);
+ }
+ } while (*sFormat);
+
+ //
+ // Write remaining data, if any
+ //
+ if (BufferDesc.Cnt != 0u) {
+ *(BufferDesc.pPayloadStart) = BufferDesc.Cnt;
+ ENCODE_U32(BufferDesc.pPayload, BufferDesc.Options);
+ ENCODE_U32(BufferDesc.pPayload, 0);
+ _SendPacket(BufferDesc.pPayloadStart, BufferDesc.pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
+ }
+#if SEGGER_SYSVIEW_USE_STATIC_BUFFER == 0
+ SEGGER_SYSVIEW_UNLOCK();
+ RECORD_END();
+#else
+ RECORD_END();
+#endif
+}
+#endif // SEGGER_SYSVIEW_EXCLUDE_PRINTF
+
+/*********************************************************************
+*
+* Public functions
+*
+**********************************************************************
+*/
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_Init()
+*
+* Function description
+* Initializes the SYSVIEW module.
+* Must be called before SystemViewer attaches to the system.
+*
+* Parameters
+* SysFreq - Frequency of timestamp, i.e. CPU core clock frequency.
+* CPUFreq - CPU core clock frequency.
+* pOSAPI - Pointer to the API structure for OS-specific functions.
+* pfSendSysDesc - Pointer to SendSysDesc callback function.
+*
+* Additional information
+* This function initializes the RTT channel used to transport
+* SEGGER SystemView packets.
+* The channel is assigned the label "SysView" for client software
+* to identify the SystemView channel.
+*
+* Notes
+* The channel is configured by the macro SEGGER_SYSVIEW_RTT_CHANNEL.
+*/
+void SEGGER_SYSVIEW_Init(U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc) {
+#ifdef SEGGER_RTT_SECTION
+ //
+ // Explicitly initialize the RTT Control Block if it is in its dedicated section.
+ //
+ SEGGER_RTT_Init();
+#endif
+#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
+#if SEGGER_SYSVIEW_RTT_CHANNEL > 0
+ SEGGER_RTT_ConfigUpBuffer(SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
+#else
+ _SYSVIEW_Globals.UpChannel = SEGGER_RTT_AllocUpBuffer ("SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
+#endif
+ _SYSVIEW_Globals.RAMBaseAddress = SEGGER_SYSVIEW_ID_BASE;
+ _SYSVIEW_Globals.LastTxTimeStamp = SEGGER_SYSVIEW_GET_TIMESTAMP();
+ _SYSVIEW_Globals.pOSAPI = pOSAPI;
+ _SYSVIEW_Globals.SysFreq = SysFreq;
+ _SYSVIEW_Globals.CPUFreq = CPUFreq;
+ _SYSVIEW_Globals.pfSendSysDesc = pfSendSysDesc;
+ _SYSVIEW_Globals.EnableState = 0;
+ _SYSVIEW_Globals.PacketCount = 0;
+#else // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
+#if SEGGER_SYSVIEW_RTT_CHANNEL > 0
+ SEGGER_RTT_ConfigUpBuffer (SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
+ SEGGER_RTT_ConfigDownBuffer (SEGGER_SYSVIEW_RTT_CHANNEL, "SysView", &_DownBuffer[0], sizeof(_DownBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
+#else
+ _SYSVIEW_Globals.UpChannel = SEGGER_RTT_AllocUpBuffer ("SysView", &_UpBuffer[0], sizeof(_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
+ //
+ // TODO: Use SEGGER_RTT_AllocDownBuffer when SystemViewer is able to handle another Down Channel than Up Channel.
+ //
+ _SYSVIEW_Globals.DownChannel = _SYSVIEW_Globals.UpChannel;
+ SEGGER_RTT_ConfigDownBuffer (_SYSVIEW_Globals.DownChannel, "SysView", &_DownBuffer[0], sizeof(_DownBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
+#endif
+ _SYSVIEW_Globals.RAMBaseAddress = SEGGER_SYSVIEW_ID_BASE;
+ _SYSVIEW_Globals.LastTxTimeStamp = SEGGER_SYSVIEW_GET_TIMESTAMP();
+ _SYSVIEW_Globals.pOSAPI = pOSAPI;
+ _SYSVIEW_Globals.SysFreq = SysFreq;
+ _SYSVIEW_Globals.CPUFreq = CPUFreq;
+ _SYSVIEW_Globals.pfSendSysDesc = pfSendSysDesc;
+ _SYSVIEW_Globals.EnableState = 0;
+#endif // (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_SetRAMBase()
+*
+* Function description
+* Sets the RAM base address, which is subtracted from IDs in order
+* to save bandwidth.
+*
+* Parameters
+* RAMBaseAddress - Lowest RAM Address. (i.e. 0x20000000 on most Cortex-M)
+*/
+void SEGGER_SYSVIEW_SetRAMBase(U32 RAMBaseAddress) {
+ _SYSVIEW_Globals.RAMBaseAddress = RAMBaseAddress;
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordVoid()
+*
+* Function description
+* Formats and sends a SystemView packet with an empty payload.
+*
+* Parameters
+* EventID - SystemView event ID.
+*/
+void SEGGER_SYSVIEW_RecordVoid(unsigned int EventID) {
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
+ //
+ _SendPacket(pPayloadStart, pPayloadStart, EventID);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordU32()
+*
+* Function description
+* Formats and sends a SystemView packet containing a single U32
+* parameter payload.
+*
+* Parameters
+* EventID - SystemView event ID.
+* Value - The 32-bit parameter encoded to SystemView packet payload.
+*/
+void SEGGER_SYSVIEW_RecordU32(unsigned int EventID, U32 Value) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, Value);
+ _SendPacket(pPayloadStart, pPayload, EventID);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordU32x2()
+*
+* Function description
+* Formats and sends a SystemView packet containing 2 U32 parameter payload.
+*
+* Parameters
+* EventID - SystemView event ID.
+* Para0 - The 32-bit parameter encoded to SystemView packet payload.
+* Para1 - The 32-bit parameter encoded to SystemView packet payload.
+*/
+void SEGGER_SYSVIEW_RecordU32x2(unsigned int EventID, U32 Para0, U32 Para1) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, Para0);
+ ENCODE_U32(pPayload, Para1);
+ _SendPacket(pPayloadStart, pPayload, EventID);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordU32x3()
+*
+* Function description
+* Formats and sends a SystemView packet containing 3 U32 parameter payload.
+*
+* Parameters
+* EventID - SystemView event ID.
+* Para0 - The 32-bit parameter encoded to SystemView packet payload.
+* Para1 - The 32-bit parameter encoded to SystemView packet payload.
+* Para2 - The 32-bit parameter encoded to SystemView packet payload.
+*/
+void SEGGER_SYSVIEW_RecordU32x3(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 3 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, Para0);
+ ENCODE_U32(pPayload, Para1);
+ ENCODE_U32(pPayload, Para2);
+ _SendPacket(pPayloadStart, pPayload, EventID);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordU32x4()
+*
+* Function description
+* Formats and sends a SystemView packet containing 4 U32 parameter payload.
+*
+* Parameters
+* EventID - SystemView event ID.
+* Para0 - The 32-bit parameter encoded to SystemView packet payload.
+* Para1 - The 32-bit parameter encoded to SystemView packet payload.
+* Para2 - The 32-bit parameter encoded to SystemView packet payload.
+* Para3 - The 32-bit parameter encoded to SystemView packet payload.
+*/
+void SEGGER_SYSVIEW_RecordU32x4(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, Para0);
+ ENCODE_U32(pPayload, Para1);
+ ENCODE_U32(pPayload, Para2);
+ ENCODE_U32(pPayload, Para3);
+ _SendPacket(pPayloadStart, pPayload, EventID);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordU32x5()
+*
+* Function description
+* Formats and sends a SystemView packet containing 5 U32 parameter payload.
+*
+* Parameters
+* EventID - SystemView event ID.
+* Para0 - The 32-bit parameter encoded to SystemView packet payload.
+* Para1 - The 32-bit parameter encoded to SystemView packet payload.
+* Para2 - The 32-bit parameter encoded to SystemView packet payload.
+* Para3 - The 32-bit parameter encoded to SystemView packet payload.
+* Para4 - The 32-bit parameter encoded to SystemView packet payload.
+*/
+void SEGGER_SYSVIEW_RecordU32x5(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, Para0);
+ ENCODE_U32(pPayload, Para1);
+ ENCODE_U32(pPayload, Para2);
+ ENCODE_U32(pPayload, Para3);
+ ENCODE_U32(pPayload, Para4);
+ _SendPacket(pPayloadStart, pPayload, EventID);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordU32x6()
+*
+* Function description
+* Formats and sends a SystemView packet containing 6 U32 parameter payload.
+*
+* Parameters
+* EventID - SystemView event ID.
+* Para0 - The 32-bit parameter encoded to SystemView packet payload.
+* Para1 - The 32-bit parameter encoded to SystemView packet payload.
+* Para2 - The 32-bit parameter encoded to SystemView packet payload.
+* Para3 - The 32-bit parameter encoded to SystemView packet payload.
+* Para4 - The 32-bit parameter encoded to SystemView packet payload.
+* Para5 - The 32-bit parameter encoded to SystemView packet payload.
+*/
+void SEGGER_SYSVIEW_RecordU32x6(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 6 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, Para0);
+ ENCODE_U32(pPayload, Para1);
+ ENCODE_U32(pPayload, Para2);
+ ENCODE_U32(pPayload, Para3);
+ ENCODE_U32(pPayload, Para4);
+ ENCODE_U32(pPayload, Para5);
+ _SendPacket(pPayloadStart, pPayload, EventID);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordU32x7()
+*
+* Function description
+* Formats and sends a SystemView packet containing 7 U32 parameter payload.
+*
+* Parameters
+* EventID - SystemView event ID.
+* Para0 - The 32-bit parameter encoded to SystemView packet payload.
+* Para1 - The 32-bit parameter encoded to SystemView packet payload.
+* Para2 - The 32-bit parameter encoded to SystemView packet payload.
+* Para3 - The 32-bit parameter encoded to SystemView packet payload.
+* Para4 - The 32-bit parameter encoded to SystemView packet payload.
+* Para5 - The 32-bit parameter encoded to SystemView packet payload.
+* Para6 - The 32-bit parameter encoded to SystemView packet payload.
+*/
+void SEGGER_SYSVIEW_RecordU32x7(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 7 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, Para0);
+ ENCODE_U32(pPayload, Para1);
+ ENCODE_U32(pPayload, Para2);
+ ENCODE_U32(pPayload, Para3);
+ ENCODE_U32(pPayload, Para4);
+ ENCODE_U32(pPayload, Para5);
+ ENCODE_U32(pPayload, Para6);
+ _SendPacket(pPayloadStart, pPayload, EventID);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordU32x8()
+*
+* Function description
+* Formats and sends a SystemView packet containing 8 U32 parameter payload.
+*
+* Parameters
+* EventID - SystemView event ID.
+* Para0 - The 32-bit parameter encoded to SystemView packet payload.
+* Para1 - The 32-bit parameter encoded to SystemView packet payload.
+* Para2 - The 32-bit parameter encoded to SystemView packet payload.
+* Para3 - The 32-bit parameter encoded to SystemView packet payload.
+* Para4 - The 32-bit parameter encoded to SystemView packet payload.
+* Para5 - The 32-bit parameter encoded to SystemView packet payload.
+* Para6 - The 32-bit parameter encoded to SystemView packet payload.
+* Para7 - The 32-bit parameter encoded to SystemView packet payload.
+*/
+void SEGGER_SYSVIEW_RecordU32x8(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 8 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, Para0);
+ ENCODE_U32(pPayload, Para1);
+ ENCODE_U32(pPayload, Para2);
+ ENCODE_U32(pPayload, Para3);
+ ENCODE_U32(pPayload, Para4);
+ ENCODE_U32(pPayload, Para5);
+ ENCODE_U32(pPayload, Para6);
+ ENCODE_U32(pPayload, Para7);
+ _SendPacket(pPayloadStart, pPayload, EventID);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordU32x9()
+*
+* Function description
+* Formats and sends a SystemView packet containing 9 U32 parameter payload.
+*
+* Parameters
+* EventID - SystemView event ID.
+* Para0 - The 32-bit parameter encoded to SystemView packet payload.
+* Para1 - The 32-bit parameter encoded to SystemView packet payload.
+* Para2 - The 32-bit parameter encoded to SystemView packet payload.
+* Para3 - The 32-bit parameter encoded to SystemView packet payload.
+* Para4 - The 32-bit parameter encoded to SystemView packet payload.
+* Para5 - The 32-bit parameter encoded to SystemView packet payload.
+* Para6 - The 32-bit parameter encoded to SystemView packet payload.
+* Para7 - The 32-bit parameter encoded to SystemView packet payload.
+* Para8 - The 32-bit parameter encoded to SystemView packet payload.
+*/
+void SEGGER_SYSVIEW_RecordU32x9(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 9 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, Para0);
+ ENCODE_U32(pPayload, Para1);
+ ENCODE_U32(pPayload, Para2);
+ ENCODE_U32(pPayload, Para3);
+ ENCODE_U32(pPayload, Para4);
+ ENCODE_U32(pPayload, Para5);
+ ENCODE_U32(pPayload, Para6);
+ ENCODE_U32(pPayload, Para7);
+ ENCODE_U32(pPayload, Para8);
+ _SendPacket(pPayloadStart, pPayload, EventID);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordU32x10()
+*
+* Function description
+* Formats and sends a SystemView packet containing 10 U32 parameter payload.
+*
+* Parameters
+* EventID - SystemView event ID.
+* Para0 - The 32-bit parameter encoded to SystemView packet payload.
+* Para1 - The 32-bit parameter encoded to SystemView packet payload.
+* Para2 - The 32-bit parameter encoded to SystemView packet payload.
+* Para3 - The 32-bit parameter encoded to SystemView packet payload.
+* Para4 - The 32-bit parameter encoded to SystemView packet payload.
+* Para5 - The 32-bit parameter encoded to SystemView packet payload.
+* Para6 - The 32-bit parameter encoded to SystemView packet payload.
+* Para7 - The 32-bit parameter encoded to SystemView packet payload.
+* Para8 - The 32-bit parameter encoded to SystemView packet payload.
+* Para9 - The 32-bit parameter encoded to SystemView packet payload.
+*/
+void SEGGER_SYSVIEW_RecordU32x10(unsigned int EventID, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8, U32 Para9) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 10 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, Para0);
+ ENCODE_U32(pPayload, Para1);
+ ENCODE_U32(pPayload, Para2);
+ ENCODE_U32(pPayload, Para3);
+ ENCODE_U32(pPayload, Para4);
+ ENCODE_U32(pPayload, Para5);
+ ENCODE_U32(pPayload, Para6);
+ ENCODE_U32(pPayload, Para7);
+ ENCODE_U32(pPayload, Para8);
+ ENCODE_U32(pPayload, Para9);
+ _SendPacket(pPayloadStart, pPayload, EventID);
+ RECORD_END();
+}
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordString()
+*
+* Function description
+* Formats and sends a SystemView packet containing a string.
+*
+* Parameters
+* EventID - SystemView event ID.
+* pString - The string to be sent in the SystemView packet payload.
+*
+* Additional information
+* The string is encoded as a count byte followed by the contents
+* of the string.
+* No more than SEGGER_SYSVIEW_MAX_STRING_LEN bytes will be encoded to the payload.
+*/
+void SEGGER_SYSVIEW_RecordString(unsigned int EventID, const char* pString) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
+ //
+ pPayload = _EncodeStr(pPayloadStart, pString, SEGGER_SYSVIEW_MAX_STRING_LEN);
+ _SendPacket(pPayloadStart, pPayload, EventID);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_Start()
+*
+* Function description
+* Start recording SystemView events.
+* This function is triggered by the host application.
+*
+* Additional information
+* This function enables transmission of SystemView packets recorded
+* by subsequent trace calls and records a SystemView Start event.
+*
+* As part of start, a SystemView Init packet is sent, containing the system
+* frequency. The list of current tasks, the current system time and the
+* system description string is sent, too.
+*
+* Notes
+* SEGGER_SYSVIEW_Start and SEGGER_SYSVIEW_Stop do not nest.
+*/
+void SEGGER_SYSVIEW_Start(void) {
+ if (_SYSVIEW_Globals.EnableState == 0) {
+ _SYSVIEW_Globals.EnableState = 1;
+#if (SEGGER_SYSVIEW_POST_MORTEM_MODE == 1)
+ _SendSyncInfo();
+#else
+ SEGGER_SYSVIEW_LOCK();
+ SEGGER_RTT_WriteSkipNoLock(CHANNEL_ID_UP, _abSync, 10);
+ SEGGER_SYSVIEW_UNLOCK();
+ SEGGER_SYSVIEW_RecordVoid(SYSVIEW_EVTID_TRACE_START);
+ {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, _SYSVIEW_Globals.SysFreq);
+ ENCODE_U32(pPayload, _SYSVIEW_Globals.CPUFreq);
+ ENCODE_U32(pPayload, _SYSVIEW_Globals.RAMBaseAddress);
+ ENCODE_U32(pPayload, SEGGER_SYSVIEW_ID_SHIFT);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_INIT);
+ RECORD_END();
+ }
+ if (_SYSVIEW_Globals.pfSendSysDesc) {
+ _SYSVIEW_Globals.pfSendSysDesc();
+ }
+ SEGGER_SYSVIEW_RecordSystime();
+ SEGGER_SYSVIEW_SendTaskList();
+ SEGGER_SYSVIEW_SendNumModules();
+#endif
+ }
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_Stop()
+*
+* Function description
+* Stop recording SystemView events.
+*
+* Additional information
+* This function disables transmission of SystemView packets recorded
+* by subsequent trace calls. If transmission is enabled when
+* this function is called, a single SystemView Stop event is recorded
+* to the trace, send, and then trace transmission is halted.
+*/
+void SEGGER_SYSVIEW_Stop(void) {
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
+ //
+ if (_SYSVIEW_Globals.EnableState) {
+ _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_TRACE_STOP);
+ _SYSVIEW_Globals.EnableState = 0;
+ }
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_GetSysDesc()
+*
+* Function description
+* Triggers a send of the system information and description.
+*
+*/
+void SEGGER_SYSVIEW_GetSysDesc(void) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, _SYSVIEW_Globals.SysFreq);
+ ENCODE_U32(pPayload, _SYSVIEW_Globals.CPUFreq);
+ ENCODE_U32(pPayload, _SYSVIEW_Globals.RAMBaseAddress);
+ ENCODE_U32(pPayload, SEGGER_SYSVIEW_ID_SHIFT);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_INIT);
+ RECORD_END();
+ if (_SYSVIEW_Globals.pfSendSysDesc) {
+ _SYSVIEW_Globals.pfSendSysDesc();
+ }
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_SendTaskInfo()
+*
+* Function description
+* Send a Task Info Packet, containing TaskId for identification,
+* task priority and task name.
+*
+* Parameters
+* pInfo - Pointer to task information to send.
+*/
+void SEGGER_SYSVIEW_SendTaskInfo(const SEGGER_SYSVIEW_TASKINFO *pInfo) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32 + 1 + 32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, SHRINK_ID(pInfo->TaskID));
+ ENCODE_U32(pPayload, pInfo->Prio);
+ pPayload = _EncodeStr(pPayload, pInfo->sName, 32);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_INFO);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, SHRINK_ID(pInfo->TaskID));
+ ENCODE_U32(pPayload, pInfo->StackBase);
+ ENCODE_U32(pPayload, pInfo->StackSize);
+ ENCODE_U32(pPayload, 0); // Stack End, future use
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_STACK_INFO);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_SendTaskList()
+*
+* Function description
+* Send all tasks descriptors to the host.
+*/
+void SEGGER_SYSVIEW_SendTaskList(void) {
+ if (_SYSVIEW_Globals.pOSAPI && _SYSVIEW_Globals.pOSAPI->pfSendTaskList) {
+ _SYSVIEW_Globals.pOSAPI->pfSendTaskList();
+ }
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_SendSysDesc()
+*
+* Function description
+* Send the system description string to the host.
+* The system description is used by SystemViewer to identify the
+* current application and handle events accordingly.
+*
+* Parameters
+* sSysDesc - Pointer to the 0-terminated system description string.
+*
+* Additional information
+* One system description string may not exceed SEGGER_SYSVIEW_MAX_STRING_LEN characters.
+*
+* The Following items can be described in a system description string.
+* Each item is identified by its identifier, followed by '=' and the value.
+* Items are separated by ','.
+*/
+void SEGGER_SYSVIEW_SendSysDesc(const char *sSysDesc) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
+ //
+ pPayload = _EncodeStr(pPayloadStart, sSysDesc, SEGGER_SYSVIEW_MAX_STRING_LEN);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_SYSDESC);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordSystime()
+*
+* Function description
+* Formats and sends a SystemView Systime containing a single U64 or U32
+* parameter payload.
+*/
+void SEGGER_SYSVIEW_RecordSystime(void) {
+ U64 Systime;
+
+ if (_SYSVIEW_Globals.pOSAPI && _SYSVIEW_Globals.pOSAPI->pfGetTime) {
+ Systime = _SYSVIEW_Globals.pOSAPI->pfGetTime();
+ SEGGER_SYSVIEW_RecordU32x2(SYSVIEW_EVTID_SYSTIME_US,
+ (U32)(Systime),
+ (U32)(Systime >> 32));
+ } else {
+ SEGGER_SYSVIEW_RecordU32(SYSVIEW_EVTID_SYSTIME_CYCLES, SEGGER_SYSVIEW_GET_TIMESTAMP());
+ }
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordEnterISR()
+*
+* Function description
+* Format and send an ISR entry event.
+*
+* Additional information
+* Example packets sent
+* 02 0F 50 // ISR(15) Enter. Timestamp is 80 (0x50)
+*/
+void SEGGER_SYSVIEW_RecordEnterISR(U32 IrqId) {
+ unsigned v;
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ v = IrqId;//SEGGER_SYSVIEW_GET_INTERRUPT_ID();
+ ENCODE_U32(pPayload, v);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_ISR_ENTER);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordExitISR()
+*
+* Function description
+* Format and send an ISR exit event.
+*
+* Additional information
+* Format as follows:
+* 03 // Max. packet len is 6
+*
+* Example packets sent
+* 03 20 // ISR Exit. Timestamp is 32 (0x20)
+*/
+void SEGGER_SYSVIEW_RecordExitISR(void) {
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
+ //
+ _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_ISR_EXIT);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordExitISRToScheduler()
+*
+* Function description
+* Format and send an ISR exit into scheduler event.
+*
+* Additional information
+* Format as follows:
+* 18 // Max. packet len is 6
+*
+* Example packets sent
+* 18 20 // ISR Exit to Scheduler. Timestamp is 32 (0x20)
+*/
+void SEGGER_SYSVIEW_RecordExitISRToScheduler(void) {
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
+ //
+ _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_ISR_TO_SCHEDULER);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordEnterTimer()
+*
+* Function description
+* Format and send a Timer entry event.
+*
+* Parameters
+* TimerId - Id of the timer which starts.
+*/
+void SEGGER_SYSVIEW_RecordEnterTimer(U32 TimerId) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, SHRINK_ID(TimerId));
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TIMER_ENTER);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordExitTimer()
+*
+* Function description
+* Format and send a Timer exit event.
+*/
+void SEGGER_SYSVIEW_RecordExitTimer(void) {
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
+ //
+ _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_TIMER_EXIT);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordEndCall()
+*
+* Function description
+* Format and send an End API Call event without return value.
+*
+* Parameters
+* EventID - Id of API function which ends.
+*/
+void SEGGER_SYSVIEW_RecordEndCall(unsigned int EventID) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, EventID);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_END_CALL);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordEndCallU32()
+*
+* Function description
+* Format and send an End API Call event with return value.
+*
+* Parameters
+* EventID - Id of API function which ends.
+* Para0 - Return value which will be returned by the API function.
+*/
+void SEGGER_SYSVIEW_RecordEndCallU32(unsigned int EventID, U32 Para0) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, EventID);
+ ENCODE_U32(pPayload, Para0);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_END_CALL);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_OnIdle()
+*
+* Function description
+* Record an Idle event.
+*/
+void SEGGER_SYSVIEW_OnIdle(void) {
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
+ //
+ _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_IDLE);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_OnTaskCreate()
+*
+* Function description
+* Record a Task Create event. The Task Create event corresponds
+* to creating a task in the OS.
+*
+* Parameters
+* TaskId - Task ID of created task.
+*/
+void SEGGER_SYSVIEW_OnTaskCreate(U32 TaskId) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ TaskId = SHRINK_ID(TaskId);
+ ENCODE_U32(pPayload, TaskId);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_CREATE);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_OnTaskTerminate()
+*
+* Function description
+* Record a Task termination event.
+* The Task termination event corresponds to terminating a task in
+* the OS. If the TaskId is the currently active task,
+* SEGGER_SYSVIEW_OnTaskStopExec may be used, either.
+*
+* Parameters
+* TaskId - Task ID of terminated task.
+*/
+void SEGGER_SYSVIEW_OnTaskTerminate(U32 TaskId) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ TaskId = SHRINK_ID(TaskId);
+ ENCODE_U32(pPayload, TaskId);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_TERMINATE);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_OnTaskStartExec()
+*
+* Function description
+* Record a Task Start Execution event. The Task Start event
+* corresponds to when a task has started to execute rather than
+* when it is ready to execute.
+*
+* Parameters
+* TaskId - Task ID of task that started to execute.
+*/
+void SEGGER_SYSVIEW_OnTaskStartExec(U32 TaskId) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ TaskId = SHRINK_ID(TaskId);
+ ENCODE_U32(pPayload, TaskId);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_START_EXEC);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_OnTaskStopExec()
+*
+* Function description
+* Record a Task Stop Execution event. The Task Stop event
+* corresponds to when a task stops executing and terminates.
+*/
+void SEGGER_SYSVIEW_OnTaskStopExec(void) {
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE);
+ //
+ _SendPacket(pPayloadStart, pPayloadStart, SYSVIEW_EVTID_TASK_STOP_EXEC);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_OnTaskStartReady()
+*
+* Function description
+* Record a Task Start Ready event.
+*
+* Parameters
+* TaskId - Task ID of task that started to execute.
+*/
+void SEGGER_SYSVIEW_OnTaskStartReady(U32 TaskId) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ TaskId = SHRINK_ID(TaskId);
+ ENCODE_U32(pPayload, TaskId);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_START_READY);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_OnTaskStopReady()
+*
+* Function description
+* Record a Task Stop Ready event.
+*
+* Parameters
+* TaskId - Task ID of task that completed execution.
+* Cause - Reason for task to stop (i.e. Idle/Sleep)
+*/
+void SEGGER_SYSVIEW_OnTaskStopReady(U32 TaskId, unsigned int Cause) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ TaskId = SHRINK_ID(TaskId);
+ ENCODE_U32(pPayload, TaskId);
+ ENCODE_U32(pPayload, Cause);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_TASK_STOP_READY);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_OnUserStart()
+*
+* Function description
+* Send a user event start, such as start of a subroutine for profiling.
+*
+* Parameters
+* UserId - User defined ID for the event.
+*/
+void SEGGER_SYSVIEW_OnUserStart(unsigned UserId) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, UserId);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_USER_START);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_OnUserStop()
+*
+* Function description
+* Send a user event stop, such as return of a subroutine for profiling.
+*
+* Parameters
+* UserId - User defined ID for the event.
+*/
+void SEGGER_SYSVIEW_OnUserStop(unsigned UserId) {
+ U8 * pPayload;
+ U8 * pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, UserId);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_USER_STOP);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_NameResource()
+*
+* Function description
+* Send the name of a resource to be displayed in SystemViewer.
+*
+* Parameters
+* ResourceId - Id of the resource to be named. i.e. its address.
+* sName - Pointer to the resource name. (Max. SEGGER_SYSVIEW_MAX_STRING_LEN Bytes)
+*/
+void SEGGER_SYSVIEW_NameResource(U32 ResourceId, const char* sName) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
+ //
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, SHRINK_ID(ResourceId));
+ pPayload = _EncodeStr(pPayload, sName, SEGGER_SYSVIEW_MAX_STRING_LEN);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_NAME_RESOURCE);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_SendPacket()
+*
+* Function description
+* Send an event packet.
+*
+* Parameters
+* pPacket - Pointer to the start of the packet.
+* pPayloadEnd - Pointer to the end of the payload.
+* Make sure there are at least 5 bytes free after the payload.
+* EventId - Id of the event packet.
+*
+* Return value
+* !=0: Success, Message sent.
+* ==0: Buffer full, Message *NOT* sent.
+*/
+int SEGGER_SYSVIEW_SendPacket(U8* pPacket, U8* pPayloadEnd, unsigned int EventId) {
+#if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1)
+ SEGGER_SYSVIEW_LOCK();
+#endif
+ _SendPacket(pPacket + 4, pPayloadEnd, EventId);
+#if (SEGGER_SYSVIEW_USE_STATIC_BUFFER == 1)
+ SEGGER_SYSVIEW_UNLOCK();
+#endif
+ return 0;
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_EncodeU32()
+*
+* Function description
+* Encode a U32 in variable-length format.
+*
+* Parameters
+* pPayload - Pointer to where U32 will be encoded.
+* Value - The 32-bit value to be encoded.
+*
+* Return value
+* Pointer to the byte following the value, i.e. the first free
+* byte in the payload and the next position to store payload
+* content.
+*/
+U8* SEGGER_SYSVIEW_EncodeU32(U8* pPayload, U32 Value) {
+ ENCODE_U32(pPayload, Value);
+ return pPayload;
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_EncodeString()
+*
+* Function description
+* Encode a string in variable-length format.
+*
+* Parameters
+* pPayload - Pointer to where string will be encoded.
+* s - String to encode.
+* MaxLen - Maximum number of characters to encode from string.
+*
+* Return value
+* Pointer to the byte following the value, i.e. the first free
+* byte in the payload and the next position to store payload
+* content.
+*
+* Additional information
+* The string is encoded as a count byte followed by the contents
+* of the string.
+* No more than 1 + MaxLen bytes will be encoded to the payload.
+*/
+U8* SEGGER_SYSVIEW_EncodeString(U8* pPayload, const char* s, unsigned int MaxLen) {
+ return _EncodeStr(pPayload, s, MaxLen);
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_EncodeData()
+*
+* Function description
+* Encode a byte buffer in variable-length format.
+*
+* Parameters
+* pPayload - Pointer to where string will be encoded.
+* pSrc - Pointer to data buffer to be encoded.
+* NumBytes - Number of bytes in the buffer to be encoded.
+*
+* Return value
+* Pointer to the byte following the value, i.e. the first free
+* byte in the payload and the next position to store payload
+* content.
+*
+* Additional information
+* The data is encoded as a count byte followed by the contents
+* of the data buffer.
+* Make sure NumBytes + 1 bytes are free for the payload.
+*/
+U8* SEGGER_SYSVIEW_EncodeData(U8 *pPayload, const char* pSrc, unsigned int NumBytes) {
+ return _EncodeData(pPayload, pSrc, NumBytes);
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_EncodeId()
+*
+* Function description
+* Encode a 32-bit Id in shrunken variable-length format.
+*
+* Parameters
+* pPayload - Pointer to where the Id will be encoded.
+* Id - The 32-bit value to be encoded.
+*
+* Return value
+* Pointer to the byte following the value, i.e. the first free
+* byte in the payload and the next position to store payload
+* content.
+*
+* Additional information
+* The parameters to shrink an Id can be configured in
+* SEGGER_SYSVIEW_Conf.h and via SEGGER_SYSVIEW_SetRAMBase().
+* SEGGER_SYSVIEW_ID_BASE: Lowest Id reported by the application.
+* (i.e. 0x20000000 when all Ids are an address in this RAM)
+* SEGGER_SYSVIEW_ID_SHIFT: Number of bits to shift the Id to
+* save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
+*/
+U8* SEGGER_SYSVIEW_EncodeId(U8* pPayload, U32 Id) {
+ Id = SHRINK_ID(Id);
+ ENCODE_U32(pPayload, Id);
+ return pPayload;
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_ShrinkId()
+*
+* Function description
+* Get the shrunken value of an Id for further processing like in
+* SEGGER_SYSVIEW_NameResource().
+*
+* Parameters
+* Id - The 32-bit value to be shrunken.
+*
+* Return value
+* Shrunken Id.
+*
+* Additional information
+* The parameters to shrink an Id can be configured in
+* SEGGER_SYSVIEW_Conf.h and via SEGGER_SYSVIEW_SetRAMBase().
+* SEGGER_SYSVIEW_ID_BASE: Lowest Id reported by the application.
+* (i.e. 0x20000000 when all Ids are an address in this RAM)
+* SEGGER_SYSVIEW_ID_SHIFT: Number of bits to shift the Id to
+* save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
+*/
+U32 SEGGER_SYSVIEW_ShrinkId(U32 Id) {
+ return SHRINK_ID(Id);
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RegisterModule()
+*
+* Function description
+* Register a middleware module for recording its events.
+*
+* Parameters
+* pModule - The middleware module information.
+*
+* Additional information
+* SEGGER_SYSVIEW_MODULE elements:
+* sDescription - Pointer to a string containing the module name and optionally the module event description.
+* NumEvents - Number of events the module wants to register.
+* EventOffset - Offset to be added to the event Ids. Out parameter, set by this function. Do not modify after calling this function.
+* pfSendModuleDesc - Callback function pointer to send more detailed module description to SystemViewer.
+* pNext - Pointer to next registered module. Out parameter, set by this function. Do not modify after calling this function.
+*/
+void SEGGER_SYSVIEW_RegisterModule(SEGGER_SYSVIEW_MODULE* pModule) {
+ SEGGER_SYSVIEW_LOCK();
+ if (_pFirstModule == 0) {
+ //
+ // No module registered, yet.
+ // Start list with new module.
+ // EventOffset is the base offset for modules
+ //
+ pModule->EventOffset = MODULE_EVENT_OFFSET;
+ pModule->pNext = 0;
+ _pFirstModule = pModule;
+ _NumModules = 1;
+ } else {
+ //
+ // Registreded module(s) present.
+ // Prepend new module in list.
+ // EventOffset set from number of events and offset of previous module.
+ //
+ pModule->EventOffset = _pFirstModule->EventOffset + _pFirstModule->NumEvents;
+ pModule->pNext = _pFirstModule;
+ _pFirstModule = pModule;
+ _NumModules++;
+ }
+ SEGGER_SYSVIEW_SendModule(0);
+ if (pModule->pfSendModuleDesc) {
+ pModule->pfSendModuleDesc();
+ }
+ SEGGER_SYSVIEW_UNLOCK();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_RecordModuleDescription()
+*
+* Function description
+* Sends detailed information of a registered module to the host.
+*
+* Parameters
+* pModule - Pointer to the described module.
+* sDescription - Pointer to a description string.
+*/
+void SEGGER_SYSVIEW_RecordModuleDescription(const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription) {
+ U8 ModuleId;
+ SEGGER_SYSVIEW_MODULE* p;
+
+ p = _pFirstModule;
+ ModuleId = 0;
+ do {
+ if (p == pModule) {
+ break;
+ }
+ ModuleId++;
+ p = p->pNext;
+ } while (p);
+ {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
+ //
+ pPayload = pPayloadStart;
+ //
+ // Send module description
+ // Send event offset and number of events
+ //
+ ENCODE_U32(pPayload, ModuleId);
+ ENCODE_U32(pPayload, (pModule->EventOffset));
+ pPayload = _EncodeStr(pPayload, sDescription, SEGGER_SYSVIEW_MAX_STRING_LEN);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MODULEDESC);
+ RECORD_END();
+ }
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_SendModule()
+*
+* Function description
+* Sends the information of a registered module to the host.
+*
+* Parameters
+* ModuleId - Id of the requested module.
+*/
+void SEGGER_SYSVIEW_SendModule(U8 ModuleId) {
+ SEGGER_SYSVIEW_MODULE* pModule;
+ U32 n;
+
+ if (_pFirstModule != 0) {
+ pModule = _pFirstModule;
+ for (n = 0; n < ModuleId; n++) {
+ pModule = pModule->pNext;
+ if (pModule == 0) {
+ break;
+ }
+ }
+ if (pModule != 0) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + 1 + SEGGER_SYSVIEW_MAX_STRING_LEN);
+ //
+ pPayload = pPayloadStart;
+ //
+ // Send module description
+ // Send event offset and number of events
+ //
+ ENCODE_U32(pPayload, ModuleId);
+ ENCODE_U32(pPayload, (pModule->EventOffset));
+ pPayload = _EncodeStr(pPayload, pModule->sModule, SEGGER_SYSVIEW_MAX_STRING_LEN);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_MODULEDESC);
+ RECORD_END();
+ }
+ }
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_SendModuleDescription()
+*
+* Function description
+* Triggers a send of the registered module descriptions.
+*
+*/
+void SEGGER_SYSVIEW_SendModuleDescription(void) {
+ SEGGER_SYSVIEW_MODULE* pModule;
+
+ if (_pFirstModule != 0) {
+ pModule = _pFirstModule;
+ do {
+ if (pModule->pfSendModuleDesc) {
+ pModule->pfSendModuleDesc();
+ }
+ pModule = pModule->pNext;
+ } while (pModule);
+ }
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_SendNumModules()
+*
+* Function description
+* Send the number of registered modules to the host.
+*/
+void SEGGER_SYSVIEW_SendNumModules(void) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2*SEGGER_SYSVIEW_QUANTA_U32);
+ pPayload = pPayloadStart;
+ ENCODE_U32(pPayload, _NumModules);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_NUMMODULES);
+ RECORD_END();
+}
+
+#ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_PrintfHostEx()
+*
+* Function description
+* Print a string which is formatted on the host by SystemViewer
+* with Additional information.
+*
+* Parameters
+* s - String to be formatted.
+* Options - Options for the string. i.e. Log level.
+*
+* Additional information
+* All format arguments are treated as 32-bit scalar values.
+*/
+void SEGGER_SYSVIEW_PrintfHostEx(const char* s, U32 Options, ...) {
+ va_list ParamList;
+
+ va_start(ParamList, Options);
+ _VPrintHost(s, Options, &ParamList);
+ va_end(ParamList);
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_PrintfHost()
+*
+* Function description
+* Print a string which is formatted on the host by SystemViewer.
+*
+* Parameters
+* s - String to be formatted.
+*
+* Additional information
+* All format arguments are treated as 32-bit scalar values.
+*/
+void SEGGER_SYSVIEW_PrintfHost(const char* s, ...) {
+ va_list ParamList;
+
+ va_start(ParamList, s);
+ _VPrintHost(s, SEGGER_SYSVIEW_LOG, &ParamList);
+ va_end(ParamList);
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_WarnfHost()
+*
+* Function description
+* Print a warnin string which is formatted on the host by
+* SystemViewer.
+*
+* Parameters
+* s - String to be formatted.
+*
+* Additional information
+* All format arguments are treated as 32-bit scalar values.
+*/
+void SEGGER_SYSVIEW_WarnfHost(const char* s, ...) {
+ va_list ParamList;
+
+ va_start(ParamList, s);
+ _VPrintHost(s, SEGGER_SYSVIEW_WARNING, &ParamList);
+ va_end(ParamList);
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_ErrorfHost()
+*
+* Function description
+* Print an error string which is formatted on the host by
+* SystemViewer.
+*
+* Parameters
+* s - String to be formatted.
+*
+* Additional information
+* All format arguments are treated as 32-bit scalar values.
+*/
+void SEGGER_SYSVIEW_ErrorfHost(const char* s, ...) {
+ va_list ParamList;
+
+ va_start(ParamList, s);
+ _VPrintHost(s, SEGGER_SYSVIEW_ERROR, &ParamList);
+ va_end(ParamList);
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_PrintfTargetEx()
+*
+* Function description
+* Print a string which is formatted on the target before sent to
+* the host with Additional information.
+*
+* Parameters
+* s - String to be formatted.
+* Options - Options for the string. i.e. Log level.
+*/
+void SEGGER_SYSVIEW_PrintfTargetEx(const char* s, U32 Options, ...) {
+ va_list ParamList;
+
+ va_start(ParamList, Options);
+ _VPrintTarget(s, Options, &ParamList);
+ va_end(ParamList);
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_PrintfTarget()
+*
+* Function description
+* Print a string which is formatted on the target before sent to
+* the host.
+*
+* Parameters
+* s - String to be formatted.
+*/
+void SEGGER_SYSVIEW_PrintfTarget(const char* s, ...) {
+ va_list ParamList;
+
+ va_start(ParamList, s);
+ _VPrintTarget(s, SEGGER_SYSVIEW_LOG, &ParamList);
+ va_end(ParamList);
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_WarnfTarget()
+*
+* Function description
+* Print a warning string which is formatted on the target before
+* sent to the host.
+*
+* Parameters
+* s - String to be formatted.
+*/
+void SEGGER_SYSVIEW_WarnfTarget(const char* s, ...) {
+ va_list ParamList;
+
+ va_start(ParamList, s);
+ _VPrintTarget(s, SEGGER_SYSVIEW_WARNING, &ParamList);
+ va_end(ParamList);
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_ErrorfTarget()
+*
+* Function description
+* Print an error string which is formatted on the target before
+* sent to the host.
+*
+* Parameters
+* s - String to be formatted.
+*/
+void SEGGER_SYSVIEW_ErrorfTarget(const char* s, ...) {
+ va_list ParamList;
+
+ va_start(ParamList, s);
+ _VPrintTarget(s, SEGGER_SYSVIEW_ERROR, &ParamList);
+ va_end(ParamList);
+}
+#endif // SEGGER_SYSVIEW_EXCLUDE_PRINTF
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_Print()
+*
+* Function description
+* Print a string to the host.
+*
+* Parameters
+* s - String to sent.
+*/
+void SEGGER_SYSVIEW_Print(const char* s) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_STRING_LEN);
+ //
+ pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
+ ENCODE_U32(pPayload, SEGGER_SYSVIEW_LOG);
+ ENCODE_U32(pPayload, 0);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_Warn()
+*
+* Function description
+* Print a warning string to the host.
+*
+* Parameters
+* s - String to sent.
+*/
+void SEGGER_SYSVIEW_Warn(const char* s) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_STRING_LEN);
+ //
+ pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
+ ENCODE_U32(pPayload, SEGGER_SYSVIEW_WARNING);
+ ENCODE_U32(pPayload, 0);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_Error()
+*
+* Function description
+* Print an error string to the host.
+*
+* Parameters
+* s - String to sent.
+*/
+void SEGGER_SYSVIEW_Error(const char* s) {
+ U8* pPayload;
+ U8* pPayloadStart;
+ RECORD_START(SEGGER_SYSVIEW_INFO_SIZE + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_STRING_LEN);
+ //
+ pPayload = _EncodeStr(pPayloadStart, s, SEGGER_SYSVIEW_MAX_STRING_LEN);
+ ENCODE_U32(pPayload, SEGGER_SYSVIEW_ERROR);
+ ENCODE_U32(pPayload, 0);
+ _SendPacket(pPayloadStart, pPayload, SYSVIEW_EVTID_PRINT_FORMATTED);
+ RECORD_END();
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_EnableEvents()
+*
+* Function description
+* Enable standard SystemView events to be generated.
+*
+* Parameters
+* EnableMask - Events to be enabled.
+*/
+void SEGGER_SYSVIEW_EnableEvents(U32 EnableMask) {
+ _SYSVIEW_Globals.DisabledEvents &= ~EnableMask;
+}
+
+/*********************************************************************
+*
+* SEGGER_SYSVIEW_DisableEvents()
+*
+* Function description
+* Disable standard SystemView events to not be generated.
+*
+* Parameters
+* DisableMask - Events to be disabled.
+*/
+void SEGGER_SYSVIEW_DisableEvents(U32 DisableMask) {
+ _SYSVIEW_Globals.DisabledEvents |= DisableMask;
+}
+
+
+/*************************** End of file ****************************/
diff --git a/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW.h b/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW.h
index 79b9aca057..91cc0c6f4d 100644
--- a/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW.h
+++ b/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW.h
@@ -1,334 +1,334 @@
-/*********************************************************************
-* SEGGER Microcontroller GmbH & Co. KG *
-* The Embedded Experts *
-**********************************************************************
-* *
-* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
-* *
-* www.segger.com Support: support@segger.com *
-* *
-**********************************************************************
-* *
-* SEGGER SystemView * Real-time application analysis *
-* *
-**********************************************************************
-* *
-* All rights reserved. *
-* *
-* SEGGER strongly recommends to not make any changes *
-* to or modify the source code of this software in order to stay *
-* compatible with the RTT protocol and J-Link. *
-* *
-* Redistribution and use in source and binary forms, with or *
-* without modification, are permitted provided that the following *
-* conditions are met: *
-* *
-* o Redistributions of source code must retain the above copyright *
-* notice, this list of conditions and the following disclaimer. *
-* *
-* o Redistributions in binary form must reproduce the above *
-* copyright notice, this list of conditions and the following *
-* disclaimer in the documentation and/or other materials provided *
-* with the distribution. *
-* *
-* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
-* nor the names of its contributors may be used to endorse or *
-* promote products derived from this software without specific *
-* prior written permission. *
-* *
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
-* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
-* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
-* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
-* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
-* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
-* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
-* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
-* DAMAGE. *
-* *
-**********************************************************************
-* *
-* SystemView version: V2.42 *
-* *
-**********************************************************************
--------------------------- END-OF-HEADER -----------------------------
-File : SEGGER_SYSVIEW.h
-Purpose : System visualization API.
-Revision: $Rev: 5626 $
-*/
-
-#ifndef SEGGER_SYSVIEW_H
-#define SEGGER_SYSVIEW_H
-
-/*********************************************************************
-*
-* #include Section
-*
-**********************************************************************
-*/
-
-#include "SEGGER.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*********************************************************************
-*
-* Defines, fixed
-*
-**********************************************************************
-*/
-
-#define SEGGER_SYSVIEW_VERSION 21000
-
-#define SEGGER_SYSVIEW_INFO_SIZE 9 // Minimum size, which has to be reserved for a packet. 1-2 byte of message type, 0-2 byte of payload length, 1-5 bytes of timestamp.
-#define SEGGER_SYSVIEW_QUANTA_U32 5 // Maximum number of bytes to encode a U32, should be reserved for each 32-bit value in a packet.
-
-#define SEGGER_SYSVIEW_LOG (0u)
-#define SEGGER_SYSVIEW_WARNING (1u)
-#define SEGGER_SYSVIEW_ERROR (2u)
-#define SEGGER_SYSVIEW_FLAG_APPEND (1u << 6)
-
-#define SEGGER_SYSVIEW_PREPARE_PACKET(p) (p) + 4
-//
-// SystemView events. First 32 IDs from 0 .. 31 are reserved for these
-//
-#define SYSVIEW_EVTID_NOP 0 // Dummy packet.
-#define SYSVIEW_EVTID_OVERFLOW 1
-#define SYSVIEW_EVTID_ISR_ENTER 2
-#define SYSVIEW_EVTID_ISR_EXIT 3
-#define SYSVIEW_EVTID_TASK_START_EXEC 4
-#define SYSVIEW_EVTID_TASK_STOP_EXEC 5
-#define SYSVIEW_EVTID_TASK_START_READY 6
-#define SYSVIEW_EVTID_TASK_STOP_READY 7
-#define SYSVIEW_EVTID_TASK_CREATE 8
-#define SYSVIEW_EVTID_TASK_INFO 9
-#define SYSVIEW_EVTID_TRACE_START 10
-#define SYSVIEW_EVTID_TRACE_STOP 11
-#define SYSVIEW_EVTID_SYSTIME_CYCLES 12
-#define SYSVIEW_EVTID_SYSTIME_US 13
-#define SYSVIEW_EVTID_SYSDESC 14
-#define SYSVIEW_EVTID_USER_START 15
-#define SYSVIEW_EVTID_USER_STOP 16
-#define SYSVIEW_EVTID_IDLE 17
-#define SYSVIEW_EVTID_ISR_TO_SCHEDULER 18
-#define SYSVIEW_EVTID_TIMER_ENTER 19
-#define SYSVIEW_EVTID_TIMER_EXIT 20
-#define SYSVIEW_EVTID_STACK_INFO 21
-#define SYSVIEW_EVTID_MODULEDESC 22
-
-#define SYSVIEW_EVTID_INIT 24
-#define SYSVIEW_EVTID_NAME_RESOURCE 25
-#define SYSVIEW_EVTID_PRINT_FORMATTED 26
-#define SYSVIEW_EVTID_NUMMODULES 27
-#define SYSVIEW_EVTID_END_CALL 28
-#define SYSVIEW_EVTID_TASK_TERMINATE 29
-
-#define SYSVIEW_EVTID_EX 31
-//
-// Event masks to disable/enable events
-//
-#define SYSVIEW_EVTMASK_NOP (1 << SYSVIEW_EVTID_NOP)
-#define SYSVIEW_EVTMASK_OVERFLOW (1 << SYSVIEW_EVTID_OVERFLOW)
-#define SYSVIEW_EVTMASK_ISR_ENTER (1 << SYSVIEW_EVTID_ISR_ENTER)
-#define SYSVIEW_EVTMASK_ISR_EXIT (1 << SYSVIEW_EVTID_ISR_EXIT)
-#define SYSVIEW_EVTMASK_TASK_START_EXEC (1 << SYSVIEW_EVTID_TASK_START_EXEC)
-#define SYSVIEW_EVTMASK_TASK_STOP_EXEC (1 << SYSVIEW_EVTID_TASK_STOP_EXEC)
-#define SYSVIEW_EVTMASK_TASK_START_READY (1 << SYSVIEW_EVTID_TASK_START_READY)
-#define SYSVIEW_EVTMASK_TASK_STOP_READY (1 << SYSVIEW_EVTID_TASK_STOP_READY)
-#define SYSVIEW_EVTMASK_TASK_CREATE (1 << SYSVIEW_EVTID_TASK_CREATE)
-#define SYSVIEW_EVTMASK_TASK_INFO (1 << SYSVIEW_EVTID_TASK_INFO)
-#define SYSVIEW_EVTMASK_TRACE_START (1 << SYSVIEW_EVTID_TRACE_START)
-#define SYSVIEW_EVTMASK_TRACE_STOP (1 << SYSVIEW_EVTID_TRACE_STOP)
-#define SYSVIEW_EVTMASK_SYSTIME_CYCLES (1 << SYSVIEW_EVTID_SYSTIME_CYCLES)
-#define SYSVIEW_EVTMASK_SYSTIME_US (1 << SYSVIEW_EVTID_SYSTIME_US)
-#define SYSVIEW_EVTMASK_SYSDESC (1 << SYSVIEW_EVTID_SYSDESC)
-#define SYSVIEW_EVTMASK_USER_START (1 << SYSVIEW_EVTID_USER_START)
-#define SYSVIEW_EVTMASK_USER_STOP (1 << SYSVIEW_EVTID_USER_STOP)
-#define SYSVIEW_EVTMASK_IDLE (1 << SYSVIEW_EVTID_IDLE)
-#define SYSVIEW_EVTMASK_ISR_TO_SCHEDULER (1 << SYSVIEW_EVTID_ISR_TO_SCHEDULER)
-#define SYSVIEW_EVTMASK_TIMER_ENTER (1 << SYSVIEW_EVTID_TIMER_ENTER)
-#define SYSVIEW_EVTMASK_TIMER_EXIT (1 << SYSVIEW_EVTID_TIMER_EXIT)
-#define SYSVIEW_EVTMASK_STACK_INFO (1 << SYSVIEW_EVTID_STACK_INFO)
-#define SYSVIEW_EVTMASK_MODULEDESC (1 << SYSVIEW_EVTID_MODULEDESC)
-
-#define SYSVIEW_EVTMASK_INIT (1 << SYSVIEW_EVTID_INIT)
-#define SYSVIEW_EVTMASK_NAME_RESOURCE (1 << SYSVIEW_EVTID_NAME_RESOURCE)
-#define SYSVIEW_EVTMASK_PRINT_FORMATTED (1 << SYSVIEW_EVTID_PRINT_FORMATTED)
-#define SYSVIEW_EVTMASK_NUMMODULES (1 << SYSVIEW_EVTID_NUMMODULES)
-#define SYSVIEW_EVTMASK_END_CALL (1 << SYSVIEW_EVTID_END_CALL)
-#define SYSVIEW_EVTMASK_TASK_TERMINATE (1 << SYSVIEW_EVTID_TASK_TERMINATE)
-
-#define SYSVIEW_EVTMASK_EX (1 << SYSVIEW_EVTID_EX)
-
-#define SYSVIEW_EVTMASK_ALL_INTERRUPTS ( SYSVIEW_EVTMASK_ISR_ENTER \
- | SYSVIEW_EVTMASK_ISR_EXIT \
- | SYSVIEW_EVTMASK_ISR_TO_SCHEDULER)
-#define SYSVIEW_EVTMASK_ALL_TASKS ( SYSVIEW_EVTMASK_TASK_START_EXEC \
- | SYSVIEW_EVTMASK_TASK_STOP_EXEC \
- | SYSVIEW_EVTMASK_TASK_START_READY \
- | SYSVIEW_EVTMASK_TASK_STOP_READY \
- | SYSVIEW_EVTMASK_TASK_CREATE \
- | SYSVIEW_EVTMASK_TASK_INFO \
- | SYSVIEW_EVTMASK_STACK_INFO \
- | SYSVIEW_EVTMASK_TASK_TERMINATE)
-
-/*********************************************************************
-*
-* Structures
-*
-**********************************************************************
-*/
-
-typedef struct {
- U32 TaskID;
- const char* sName;
- U32 Prio;
- U32 StackBase;
- U32 StackSize;
-} SEGGER_SYSVIEW_TASKINFO;
-
-typedef struct SEGGER_SYSVIEW_MODULE_STRUCT SEGGER_SYSVIEW_MODULE;
-
-struct SEGGER_SYSVIEW_MODULE_STRUCT {
- const char* sModule;
- U32 NumEvents;
- U32 EventOffset;
- void (*pfSendModuleDesc)(void);
- SEGGER_SYSVIEW_MODULE* pNext;
-};
-
-typedef void (SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC)(void);
-
-/*********************************************************************
-*
-* API functions
-*
-**********************************************************************
-*/
-
-typedef struct {
- U64 (*pfGetTime) (void);
- void (*pfSendTaskList) (void);
-} SEGGER_SYSVIEW_OS_API;
-
-/*********************************************************************
-*
-* Control and initialization functions
-*/
-void SEGGER_SYSVIEW_Init (U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc);
-void SEGGER_SYSVIEW_SetRAMBase (U32 RAMBaseAddress);
-void SEGGER_SYSVIEW_Start (void);
-void SEGGER_SYSVIEW_Stop (void);
-void SEGGER_SYSVIEW_GetSysDesc (void);
-void SEGGER_SYSVIEW_SendTaskList (void);
-void SEGGER_SYSVIEW_SendTaskInfo (const SEGGER_SYSVIEW_TASKINFO* pInfo);
-void SEGGER_SYSVIEW_SendSysDesc (const char* sSysDesc);
-
-/*********************************************************************
-*
-* Event recording functions
-*/
-void SEGGER_SYSVIEW_RecordVoid (unsigned int EventId);
-void SEGGER_SYSVIEW_RecordU32 (unsigned int EventId, U32 Para0);
-void SEGGER_SYSVIEW_RecordU32x2 (unsigned int EventId, U32 Para0, U32 Para1);
-void SEGGER_SYSVIEW_RecordU32x3 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2);
-void SEGGER_SYSVIEW_RecordU32x4 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3);
-void SEGGER_SYSVIEW_RecordU32x5 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4);
-void SEGGER_SYSVIEW_RecordU32x6 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5);
-void SEGGER_SYSVIEW_RecordU32x7 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6);
-void SEGGER_SYSVIEW_RecordU32x8 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7);
-void SEGGER_SYSVIEW_RecordU32x9 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8);
-void SEGGER_SYSVIEW_RecordU32x10 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8, U32 Para9);
-void SEGGER_SYSVIEW_RecordString (unsigned int EventId, const char* pString);
-void SEGGER_SYSVIEW_RecordSystime (void);
-void SEGGER_SYSVIEW_RecordEnterISR (U32 IrqId);
-void SEGGER_SYSVIEW_RecordExitISR (void);
-void SEGGER_SYSVIEW_RecordExitISRToScheduler (void);
-void SEGGER_SYSVIEW_RecordEnterTimer (U32 TimerId);
-void SEGGER_SYSVIEW_RecordExitTimer (void);
-void SEGGER_SYSVIEW_RecordEndCall (unsigned int EventID);
-void SEGGER_SYSVIEW_RecordEndCallU32 (unsigned int EventID, U32 Para0);
-
-void SEGGER_SYSVIEW_OnIdle (void);
-void SEGGER_SYSVIEW_OnTaskCreate (U32 TaskId);
-void SEGGER_SYSVIEW_OnTaskTerminate (U32 TaskId);
-void SEGGER_SYSVIEW_OnTaskStartExec (U32 TaskId);
-void SEGGER_SYSVIEW_OnTaskStopExec (void);
-void SEGGER_SYSVIEW_OnTaskStartReady (U32 TaskId);
-void SEGGER_SYSVIEW_OnTaskStopReady (U32 TaskId, unsigned int Cause);
-void SEGGER_SYSVIEW_OnUserStart (unsigned int UserId); // Start of user defined event (such as a subroutine to profile)
-void SEGGER_SYSVIEW_OnUserStop (unsigned int UserId); // Start of user defined event
-
-void SEGGER_SYSVIEW_NameResource (U32 ResourceId, const char* sName);
-
-int SEGGER_SYSVIEW_SendPacket (U8* pPacket, U8* pPayloadEnd, unsigned int EventId);
-
-/*********************************************************************
-*
-* Event parameter encoding functions
-*/
-U8* SEGGER_SYSVIEW_EncodeU32 (U8* pPayload, U32 Value);
-U8* SEGGER_SYSVIEW_EncodeData (U8* pPayload, const char* pSrc, unsigned int Len);
-U8* SEGGER_SYSVIEW_EncodeString (U8* pPayload, const char* s, unsigned int MaxLen);
-U8* SEGGER_SYSVIEW_EncodeId (U8* pPayload, U32 Id);
-U32 SEGGER_SYSVIEW_ShrinkId (U32 Id);
-
-
-/*********************************************************************
-*
-* Middleware module registration
-*/
-void SEGGER_SYSVIEW_RegisterModule (SEGGER_SYSVIEW_MODULE* pModule);
-void SEGGER_SYSVIEW_RecordModuleDescription (const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription);
-void SEGGER_SYSVIEW_SendModule (U8 ModuleId);
-void SEGGER_SYSVIEW_SendModuleDescription (void);
-void SEGGER_SYSVIEW_SendNumModules (void);
-
-/*********************************************************************
-*
-* printf-Style functions
-*/
-#ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
-void SEGGER_SYSVIEW_PrintfHostEx (const char* s, U32 Options, ...);
-void SEGGER_SYSVIEW_PrintfTargetEx (const char* s, U32 Options, ...);
-void SEGGER_SYSVIEW_PrintfHost (const char* s, ...);
-void SEGGER_SYSVIEW_PrintfTarget (const char* s, ...);
-void SEGGER_SYSVIEW_WarnfHost (const char* s, ...);
-void SEGGER_SYSVIEW_WarnfTarget (const char* s, ...);
-void SEGGER_SYSVIEW_ErrorfHost (const char* s, ...);
-void SEGGER_SYSVIEW_ErrorfTarget (const char* s, ...);
-#endif
-
-void SEGGER_SYSVIEW_Print (const char* s);
-void SEGGER_SYSVIEW_Warn (const char* s);
-void SEGGER_SYSVIEW_Error (const char* s);
-
-/*********************************************************************
-*
-* Run-time configuration functions
-*/
-void SEGGER_SYSVIEW_EnableEvents (U32 EnableMask);
-void SEGGER_SYSVIEW_DisableEvents (U32 DisableMask);
-
-/*********************************************************************
-*
-* Application-provided functions
-*/
-void SEGGER_SYSVIEW_Conf (void);
-U32 SEGGER_SYSVIEW_X_GetTimestamp (void);
-U32 SEGGER_SYSVIEW_X_GetInterruptId (void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-/*************************** End of file ****************************/
+/*********************************************************************
+* SEGGER Microcontroller GmbH & Co. KG *
+* The Embedded Experts *
+**********************************************************************
+* *
+* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
+* *
+* www.segger.com Support: support@segger.com *
+* *
+**********************************************************************
+* *
+* SEGGER SystemView * Real-time application analysis *
+* *
+**********************************************************************
+* *
+* All rights reserved. *
+* *
+* SEGGER strongly recommends to not make any changes *
+* to or modify the source code of this software in order to stay *
+* compatible with the RTT protocol and J-Link. *
+* *
+* Redistribution and use in source and binary forms, with or *
+* without modification, are permitted provided that the following *
+* conditions are met: *
+* *
+* o Redistributions of source code must retain the above copyright *
+* notice, this list of conditions and the following disclaimer. *
+* *
+* o Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the following *
+* disclaimer in the documentation and/or other materials provided *
+* with the distribution. *
+* *
+* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
+* nor the names of its contributors may be used to endorse or *
+* promote products derived from this software without specific *
+* prior written permission. *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
+* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
+* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
+* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
+* DAMAGE. *
+* *
+**********************************************************************
+* *
+* SystemView version: V2.42 *
+* *
+**********************************************************************
+-------------------------- END-OF-HEADER -----------------------------
+File : SEGGER_SYSVIEW.h
+Purpose : System visualization API.
+Revision: $Rev: 5626 $
+*/
+
+#ifndef SEGGER_SYSVIEW_H
+#define SEGGER_SYSVIEW_H
+
+/*********************************************************************
+*
+* #include Section
+*
+**********************************************************************
+*/
+
+#include "SEGGER.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*********************************************************************
+*
+* Defines, fixed
+*
+**********************************************************************
+*/
+
+#define SEGGER_SYSVIEW_VERSION 21000
+
+#define SEGGER_SYSVIEW_INFO_SIZE 9 // Minimum size, which has to be reserved for a packet. 1-2 byte of message type, 0-2 byte of payload length, 1-5 bytes of timestamp.
+#define SEGGER_SYSVIEW_QUANTA_U32 5 // Maximum number of bytes to encode a U32, should be reserved for each 32-bit value in a packet.
+
+#define SEGGER_SYSVIEW_LOG (0u)
+#define SEGGER_SYSVIEW_WARNING (1u)
+#define SEGGER_SYSVIEW_ERROR (2u)
+#define SEGGER_SYSVIEW_FLAG_APPEND (1u << 6)
+
+#define SEGGER_SYSVIEW_PREPARE_PACKET(p) (p) + 4
+//
+// SystemView events. First 32 IDs from 0 .. 31 are reserved for these
+//
+#define SYSVIEW_EVTID_NOP 0 // Dummy packet.
+#define SYSVIEW_EVTID_OVERFLOW 1
+#define SYSVIEW_EVTID_ISR_ENTER 2
+#define SYSVIEW_EVTID_ISR_EXIT 3
+#define SYSVIEW_EVTID_TASK_START_EXEC 4
+#define SYSVIEW_EVTID_TASK_STOP_EXEC 5
+#define SYSVIEW_EVTID_TASK_START_READY 6
+#define SYSVIEW_EVTID_TASK_STOP_READY 7
+#define SYSVIEW_EVTID_TASK_CREATE 8
+#define SYSVIEW_EVTID_TASK_INFO 9
+#define SYSVIEW_EVTID_TRACE_START 10
+#define SYSVIEW_EVTID_TRACE_STOP 11
+#define SYSVIEW_EVTID_SYSTIME_CYCLES 12
+#define SYSVIEW_EVTID_SYSTIME_US 13
+#define SYSVIEW_EVTID_SYSDESC 14
+#define SYSVIEW_EVTID_USER_START 15
+#define SYSVIEW_EVTID_USER_STOP 16
+#define SYSVIEW_EVTID_IDLE 17
+#define SYSVIEW_EVTID_ISR_TO_SCHEDULER 18
+#define SYSVIEW_EVTID_TIMER_ENTER 19
+#define SYSVIEW_EVTID_TIMER_EXIT 20
+#define SYSVIEW_EVTID_STACK_INFO 21
+#define SYSVIEW_EVTID_MODULEDESC 22
+
+#define SYSVIEW_EVTID_INIT 24
+#define SYSVIEW_EVTID_NAME_RESOURCE 25
+#define SYSVIEW_EVTID_PRINT_FORMATTED 26
+#define SYSVIEW_EVTID_NUMMODULES 27
+#define SYSVIEW_EVTID_END_CALL 28
+#define SYSVIEW_EVTID_TASK_TERMINATE 29
+
+#define SYSVIEW_EVTID_EX 31
+//
+// Event masks to disable/enable events
+//
+#define SYSVIEW_EVTMASK_NOP (1 << SYSVIEW_EVTID_NOP)
+#define SYSVIEW_EVTMASK_OVERFLOW (1 << SYSVIEW_EVTID_OVERFLOW)
+#define SYSVIEW_EVTMASK_ISR_ENTER (1 << SYSVIEW_EVTID_ISR_ENTER)
+#define SYSVIEW_EVTMASK_ISR_EXIT (1 << SYSVIEW_EVTID_ISR_EXIT)
+#define SYSVIEW_EVTMASK_TASK_START_EXEC (1 << SYSVIEW_EVTID_TASK_START_EXEC)
+#define SYSVIEW_EVTMASK_TASK_STOP_EXEC (1 << SYSVIEW_EVTID_TASK_STOP_EXEC)
+#define SYSVIEW_EVTMASK_TASK_START_READY (1 << SYSVIEW_EVTID_TASK_START_READY)
+#define SYSVIEW_EVTMASK_TASK_STOP_READY (1 << SYSVIEW_EVTID_TASK_STOP_READY)
+#define SYSVIEW_EVTMASK_TASK_CREATE (1 << SYSVIEW_EVTID_TASK_CREATE)
+#define SYSVIEW_EVTMASK_TASK_INFO (1 << SYSVIEW_EVTID_TASK_INFO)
+#define SYSVIEW_EVTMASK_TRACE_START (1 << SYSVIEW_EVTID_TRACE_START)
+#define SYSVIEW_EVTMASK_TRACE_STOP (1 << SYSVIEW_EVTID_TRACE_STOP)
+#define SYSVIEW_EVTMASK_SYSTIME_CYCLES (1 << SYSVIEW_EVTID_SYSTIME_CYCLES)
+#define SYSVIEW_EVTMASK_SYSTIME_US (1 << SYSVIEW_EVTID_SYSTIME_US)
+#define SYSVIEW_EVTMASK_SYSDESC (1 << SYSVIEW_EVTID_SYSDESC)
+#define SYSVIEW_EVTMASK_USER_START (1 << SYSVIEW_EVTID_USER_START)
+#define SYSVIEW_EVTMASK_USER_STOP (1 << SYSVIEW_EVTID_USER_STOP)
+#define SYSVIEW_EVTMASK_IDLE (1 << SYSVIEW_EVTID_IDLE)
+#define SYSVIEW_EVTMASK_ISR_TO_SCHEDULER (1 << SYSVIEW_EVTID_ISR_TO_SCHEDULER)
+#define SYSVIEW_EVTMASK_TIMER_ENTER (1 << SYSVIEW_EVTID_TIMER_ENTER)
+#define SYSVIEW_EVTMASK_TIMER_EXIT (1 << SYSVIEW_EVTID_TIMER_EXIT)
+#define SYSVIEW_EVTMASK_STACK_INFO (1 << SYSVIEW_EVTID_STACK_INFO)
+#define SYSVIEW_EVTMASK_MODULEDESC (1 << SYSVIEW_EVTID_MODULEDESC)
+
+#define SYSVIEW_EVTMASK_INIT (1 << SYSVIEW_EVTID_INIT)
+#define SYSVIEW_EVTMASK_NAME_RESOURCE (1 << SYSVIEW_EVTID_NAME_RESOURCE)
+#define SYSVIEW_EVTMASK_PRINT_FORMATTED (1 << SYSVIEW_EVTID_PRINT_FORMATTED)
+#define SYSVIEW_EVTMASK_NUMMODULES (1 << SYSVIEW_EVTID_NUMMODULES)
+#define SYSVIEW_EVTMASK_END_CALL (1 << SYSVIEW_EVTID_END_CALL)
+#define SYSVIEW_EVTMASK_TASK_TERMINATE (1 << SYSVIEW_EVTID_TASK_TERMINATE)
+
+#define SYSVIEW_EVTMASK_EX (1 << SYSVIEW_EVTID_EX)
+
+#define SYSVIEW_EVTMASK_ALL_INTERRUPTS ( SYSVIEW_EVTMASK_ISR_ENTER \
+ | SYSVIEW_EVTMASK_ISR_EXIT \
+ | SYSVIEW_EVTMASK_ISR_TO_SCHEDULER)
+#define SYSVIEW_EVTMASK_ALL_TASKS ( SYSVIEW_EVTMASK_TASK_START_EXEC \
+ | SYSVIEW_EVTMASK_TASK_STOP_EXEC \
+ | SYSVIEW_EVTMASK_TASK_START_READY \
+ | SYSVIEW_EVTMASK_TASK_STOP_READY \
+ | SYSVIEW_EVTMASK_TASK_CREATE \
+ | SYSVIEW_EVTMASK_TASK_INFO \
+ | SYSVIEW_EVTMASK_STACK_INFO \
+ | SYSVIEW_EVTMASK_TASK_TERMINATE)
+
+/*********************************************************************
+*
+* Structures
+*
+**********************************************************************
+*/
+
+typedef struct {
+ U32 TaskID;
+ const char* sName;
+ U32 Prio;
+ U32 StackBase;
+ U32 StackSize;
+} SEGGER_SYSVIEW_TASKINFO;
+
+typedef struct SEGGER_SYSVIEW_MODULE_STRUCT SEGGER_SYSVIEW_MODULE;
+
+struct SEGGER_SYSVIEW_MODULE_STRUCT {
+ const char* sModule;
+ U32 NumEvents;
+ U32 EventOffset;
+ void (*pfSendModuleDesc)(void);
+ SEGGER_SYSVIEW_MODULE* pNext;
+};
+
+typedef void (SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC)(void);
+
+/*********************************************************************
+*
+* API functions
+*
+**********************************************************************
+*/
+
+typedef struct {
+ U64 (*pfGetTime) (void);
+ void (*pfSendTaskList) (void);
+} SEGGER_SYSVIEW_OS_API;
+
+/*********************************************************************
+*
+* Control and initialization functions
+*/
+void SEGGER_SYSVIEW_Init (U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc);
+void SEGGER_SYSVIEW_SetRAMBase (U32 RAMBaseAddress);
+void SEGGER_SYSVIEW_Start (void);
+void SEGGER_SYSVIEW_Stop (void);
+void SEGGER_SYSVIEW_GetSysDesc (void);
+void SEGGER_SYSVIEW_SendTaskList (void);
+void SEGGER_SYSVIEW_SendTaskInfo (const SEGGER_SYSVIEW_TASKINFO* pInfo);
+void SEGGER_SYSVIEW_SendSysDesc (const char* sSysDesc);
+
+/*********************************************************************
+*
+* Event recording functions
+*/
+void SEGGER_SYSVIEW_RecordVoid (unsigned int EventId);
+void SEGGER_SYSVIEW_RecordU32 (unsigned int EventId, U32 Para0);
+void SEGGER_SYSVIEW_RecordU32x2 (unsigned int EventId, U32 Para0, U32 Para1);
+void SEGGER_SYSVIEW_RecordU32x3 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2);
+void SEGGER_SYSVIEW_RecordU32x4 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3);
+void SEGGER_SYSVIEW_RecordU32x5 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4);
+void SEGGER_SYSVIEW_RecordU32x6 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5);
+void SEGGER_SYSVIEW_RecordU32x7 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6);
+void SEGGER_SYSVIEW_RecordU32x8 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7);
+void SEGGER_SYSVIEW_RecordU32x9 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8);
+void SEGGER_SYSVIEW_RecordU32x10 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8, U32 Para9);
+void SEGGER_SYSVIEW_RecordString (unsigned int EventId, const char* pString);
+void SEGGER_SYSVIEW_RecordSystime (void);
+void SEGGER_SYSVIEW_RecordEnterISR (U32 IrqId);
+void SEGGER_SYSVIEW_RecordExitISR (void);
+void SEGGER_SYSVIEW_RecordExitISRToScheduler (void);
+void SEGGER_SYSVIEW_RecordEnterTimer (U32 TimerId);
+void SEGGER_SYSVIEW_RecordExitTimer (void);
+void SEGGER_SYSVIEW_RecordEndCall (unsigned int EventID);
+void SEGGER_SYSVIEW_RecordEndCallU32 (unsigned int EventID, U32 Para0);
+
+void SEGGER_SYSVIEW_OnIdle (void);
+void SEGGER_SYSVIEW_OnTaskCreate (U32 TaskId);
+void SEGGER_SYSVIEW_OnTaskTerminate (U32 TaskId);
+void SEGGER_SYSVIEW_OnTaskStartExec (U32 TaskId);
+void SEGGER_SYSVIEW_OnTaskStopExec (void);
+void SEGGER_SYSVIEW_OnTaskStartReady (U32 TaskId);
+void SEGGER_SYSVIEW_OnTaskStopReady (U32 TaskId, unsigned int Cause);
+void SEGGER_SYSVIEW_OnUserStart (unsigned int UserId); // Start of user defined event (such as a subroutine to profile)
+void SEGGER_SYSVIEW_OnUserStop (unsigned int UserId); // Start of user defined event
+
+void SEGGER_SYSVIEW_NameResource (U32 ResourceId, const char* sName);
+
+int SEGGER_SYSVIEW_SendPacket (U8* pPacket, U8* pPayloadEnd, unsigned int EventId);
+
+/*********************************************************************
+*
+* Event parameter encoding functions
+*/
+U8* SEGGER_SYSVIEW_EncodeU32 (U8* pPayload, U32 Value);
+U8* SEGGER_SYSVIEW_EncodeData (U8* pPayload, const char* pSrc, unsigned int Len);
+U8* SEGGER_SYSVIEW_EncodeString (U8* pPayload, const char* s, unsigned int MaxLen);
+U8* SEGGER_SYSVIEW_EncodeId (U8* pPayload, U32 Id);
+U32 SEGGER_SYSVIEW_ShrinkId (U32 Id);
+
+
+/*********************************************************************
+*
+* Middleware module registration
+*/
+void SEGGER_SYSVIEW_RegisterModule (SEGGER_SYSVIEW_MODULE* pModule);
+void SEGGER_SYSVIEW_RecordModuleDescription (const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription);
+void SEGGER_SYSVIEW_SendModule (U8 ModuleId);
+void SEGGER_SYSVIEW_SendModuleDescription (void);
+void SEGGER_SYSVIEW_SendNumModules (void);
+
+/*********************************************************************
+*
+* printf-Style functions
+*/
+#ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
+void SEGGER_SYSVIEW_PrintfHostEx (const char* s, U32 Options, ...);
+void SEGGER_SYSVIEW_PrintfTargetEx (const char* s, U32 Options, ...);
+void SEGGER_SYSVIEW_PrintfHost (const char* s, ...);
+void SEGGER_SYSVIEW_PrintfTarget (const char* s, ...);
+void SEGGER_SYSVIEW_WarnfHost (const char* s, ...);
+void SEGGER_SYSVIEW_WarnfTarget (const char* s, ...);
+void SEGGER_SYSVIEW_ErrorfHost (const char* s, ...);
+void SEGGER_SYSVIEW_ErrorfTarget (const char* s, ...);
+#endif
+
+void SEGGER_SYSVIEW_Print (const char* s);
+void SEGGER_SYSVIEW_Warn (const char* s);
+void SEGGER_SYSVIEW_Error (const char* s);
+
+/*********************************************************************
+*
+* Run-time configuration functions
+*/
+void SEGGER_SYSVIEW_EnableEvents (U32 EnableMask);
+void SEGGER_SYSVIEW_DisableEvents (U32 DisableMask);
+
+/*********************************************************************
+*
+* Application-provided functions
+*/
+void SEGGER_SYSVIEW_Conf (void);
+U32 SEGGER_SYSVIEW_X_GetTimestamp (void);
+U32 SEGGER_SYSVIEW_X_GetInterruptId (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*************************** End of file ****************************/
diff --git a/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW_ConfDefaults.h b/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW_ConfDefaults.h
index 162e6db705..f1622c6d19 100644
--- a/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW_ConfDefaults.h
+++ b/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW_ConfDefaults.h
@@ -1,178 +1,178 @@
-/*********************************************************************
-* SEGGER Microcontroller GmbH & Co. KG *
-* The Embedded Experts *
-**********************************************************************
-* *
-* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
-* *
-* www.segger.com Support: support@segger.com *
-* *
-**********************************************************************
-* *
-* SEGGER SystemView * Real-time application analysis *
-* *
-**********************************************************************
-* *
-* All rights reserved. *
-* *
-* SEGGER strongly recommends to not make any changes *
-* to or modify the source code of this software in order to stay *
-* compatible with the RTT protocol and J-Link. *
-* *
-* Redistribution and use in source and binary forms, with or *
-* without modification, are permitted provided that the following *
-* conditions are met: *
-* *
-* o Redistributions of source code must retain the above copyright *
-* notice, this list of conditions and the following disclaimer. *
-* *
-* o Redistributions in binary form must reproduce the above *
-* copyright notice, this list of conditions and the following *
-* disclaimer in the documentation and/or other materials provided *
-* with the distribution. *
-* *
-* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
-* nor the names of its contributors may be used to endorse or *
-* promote products derived from this software without specific *
-* prior written permission. *
-* *
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
-* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
-* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
-* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
-* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
-* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
-* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
-* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
-* DAMAGE. *
-* *
-**********************************************************************
-* *
-* SystemView version: V2.42 *
-* *
-**********************************************************************
--------------------------- END-OF-HEADER -----------------------------
-File : SEGGER_SYSVIEW_ConfDefaults.h
-Purpose : Defines defaults for configurable defines used in
- SEGGER SystemView.
-Revision: $Rev: 3734 $
-*/
-
-#ifndef SEGGER_SYSVIEW_CONFDEFAULTS_H
-#define SEGGER_SYSVIEW_CONFDEFAULTS_H
-
-/*********************************************************************
-*
-* #include Section
-*
-**********************************************************************
-*/
-
-#include "SEGGER_SYSVIEW_Conf.h"
-#include "SEGGER_RTT_Conf.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*********************************************************************
-*
-* Configuration defaults
-*
-**********************************************************************
-*/
-
-// Number of bytes that SystemView uses for a buffer.
-#ifndef SEGGER_SYSVIEW_RTT_BUFFER_SIZE
- #define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024
-#endif
-
-// The RTT channel that SystemView will use.
-#ifndef SEGGER_SYSVIEW_RTT_CHANNEL
- #define SEGGER_SYSVIEW_RTT_CHANNEL 0
-#endif
-// Sanity check of RTT channel
-#if (SEGGER_SYSVIEW_RTT_CHANNEL == 0) && (SEGGER_RTT_MAX_NUM_UP_BUFFERS < 2)
- #error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > 1!"
-#elif (SEGGER_SYSVIEW_RTT_CHANNEL >= SEGGER_RTT_MAX_NUM_UP_BUFFERS)
- #error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > SEGGER_SYSVIEW_RTT_CHANNEL!"
-#endif
-
-// Place the SystemView buffer into its own/the RTT section
-#if !(defined SEGGER_SYSVIEW_BUFFER_SECTION) && (defined SEGGER_RTT_SECTION)
- #define SEGGER_SYSVIEW_BUFFER_SECTION SEGGER_RTT_SECTION
-#endif
-
-// Retrieve a system timestamp. This gets the Cortex-M cycle counter.
-#ifndef SEGGER_SYSVIEW_GET_TIMESTAMP
- #error "SEGGER_SYSVIEW_GET_TIMESTAMP has to be defined in SEGGER_SYSVIEW_Conf.h!"
-#endif
-
-// Define number of valid bits low-order delivered by clock source.
-#ifndef SEGGER_SYSVIEW_TIMESTAMP_BITS
- #define SEGGER_SYSVIEW_TIMESTAMP_BITS 32
-#endif
-
-// Lowest Id reported by the Application.
-#ifndef SEGGER_SYSVIEW_ID_BASE
- #define SEGGER_SYSVIEW_ID_BASE 0
-#endif
-
-// Number of bits to shift Ids to save bandwidth
-#ifndef SEGGER_SYSVIEW_ID_SHIFT
- #define SEGGER_SYSVIEW_ID_SHIFT 0
-#endif
-
-#ifndef SEGGER_SYSVIEW_GET_INTERRUPT_ID
- #error "SEGGER_SYSVIEW_GET_INTERRUPT_ID has to be defined in SEGGER_SYSVIEW_Conf.h!"
-#endif
-
-#ifndef SEGGER_SYSVIEW_MAX_ARGUMENTS
- #define SEGGER_SYSVIEW_MAX_ARGUMENTS 16
-#endif
-
-#ifndef SEGGER_SYSVIEW_MAX_STRING_LEN
- #define SEGGER_SYSVIEW_MAX_STRING_LEN 128
-#endif
-
-// Use a static buffer instead of a buffer on the stack for packets
-#ifndef SEGGER_SYSVIEW_USE_STATIC_BUFFER
- #define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1
-#endif
-
-// Maximum packet size used by SystemView for the static buffer
-#ifndef SEGGER_SYSVIEW_MAX_PACKET_SIZE
- #define SEGGER_SYSVIEW_MAX_PACKET_SIZE SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32
-#endif
-
-// Use post-mortem analysis instead of real-time analysis
-#ifndef SEGGER_SYSVIEW_POST_MORTEM_MODE
- #define SEGGER_SYSVIEW_POST_MORTEM_MODE 0
-#endif
-
-// Configure how frequently syncronization is sent
-#ifndef SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT
- #define SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT 8
-#endif
-
-// Lock SystemView (nestable)
-#ifndef SEGGER_SYSVIEW_LOCK
- #define SEGGER_SYSVIEW_LOCK() SEGGER_RTT_LOCK()
-#endif
-
-// Unlock SystemView (nestable)
-#ifndef SEGGER_SYSVIEW_UNLOCK
- #define SEGGER_SYSVIEW_UNLOCK() SEGGER_RTT_UNLOCK()
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-/*************************** End of file ****************************/
+/*********************************************************************
+* SEGGER Microcontroller GmbH & Co. KG *
+* The Embedded Experts *
+**********************************************************************
+* *
+* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
+* *
+* www.segger.com Support: support@segger.com *
+* *
+**********************************************************************
+* *
+* SEGGER SystemView * Real-time application analysis *
+* *
+**********************************************************************
+* *
+* All rights reserved. *
+* *
+* SEGGER strongly recommends to not make any changes *
+* to or modify the source code of this software in order to stay *
+* compatible with the RTT protocol and J-Link. *
+* *
+* Redistribution and use in source and binary forms, with or *
+* without modification, are permitted provided that the following *
+* conditions are met: *
+* *
+* o Redistributions of source code must retain the above copyright *
+* notice, this list of conditions and the following disclaimer. *
+* *
+* o Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the following *
+* disclaimer in the documentation and/or other materials provided *
+* with the distribution. *
+* *
+* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
+* nor the names of its contributors may be used to endorse or *
+* promote products derived from this software without specific *
+* prior written permission. *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
+* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
+* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
+* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
+* DAMAGE. *
+* *
+**********************************************************************
+* *
+* SystemView version: V2.42 *
+* *
+**********************************************************************
+-------------------------- END-OF-HEADER -----------------------------
+File : SEGGER_SYSVIEW_ConfDefaults.h
+Purpose : Defines defaults for configurable defines used in
+ SEGGER SystemView.
+Revision: $Rev: 3734 $
+*/
+
+#ifndef SEGGER_SYSVIEW_CONFDEFAULTS_H
+#define SEGGER_SYSVIEW_CONFDEFAULTS_H
+
+/*********************************************************************
+*
+* #include Section
+*
+**********************************************************************
+*/
+
+#include "SEGGER_SYSVIEW_Conf.h"
+#include "SEGGER_RTT_Conf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*********************************************************************
+*
+* Configuration defaults
+*
+**********************************************************************
+*/
+
+// Number of bytes that SystemView uses for a buffer.
+#ifndef SEGGER_SYSVIEW_RTT_BUFFER_SIZE
+ #define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024
+#endif
+
+// The RTT channel that SystemView will use.
+#ifndef SEGGER_SYSVIEW_RTT_CHANNEL
+ #define SEGGER_SYSVIEW_RTT_CHANNEL 0
+#endif
+// Sanity check of RTT channel
+#if (SEGGER_SYSVIEW_RTT_CHANNEL == 0) && (SEGGER_RTT_MAX_NUM_UP_BUFFERS < 2)
+ #error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > 1!"
+#elif (SEGGER_SYSVIEW_RTT_CHANNEL >= SEGGER_RTT_MAX_NUM_UP_BUFFERS)
+ #error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > SEGGER_SYSVIEW_RTT_CHANNEL!"
+#endif
+
+// Place the SystemView buffer into its own/the RTT section
+#if !(defined SEGGER_SYSVIEW_BUFFER_SECTION) && (defined SEGGER_RTT_SECTION)
+ #define SEGGER_SYSVIEW_BUFFER_SECTION SEGGER_RTT_SECTION
+#endif
+
+// Retrieve a system timestamp. This gets the Cortex-M cycle counter.
+#ifndef SEGGER_SYSVIEW_GET_TIMESTAMP
+ #error "SEGGER_SYSVIEW_GET_TIMESTAMP has to be defined in SEGGER_SYSVIEW_Conf.h!"
+#endif
+
+// Define number of valid bits low-order delivered by clock source.
+#ifndef SEGGER_SYSVIEW_TIMESTAMP_BITS
+ #define SEGGER_SYSVIEW_TIMESTAMP_BITS 32
+#endif
+
+// Lowest Id reported by the Application.
+#ifndef SEGGER_SYSVIEW_ID_BASE
+ #define SEGGER_SYSVIEW_ID_BASE 0
+#endif
+
+// Number of bits to shift Ids to save bandwidth
+#ifndef SEGGER_SYSVIEW_ID_SHIFT
+ #define SEGGER_SYSVIEW_ID_SHIFT 0
+#endif
+
+#ifndef SEGGER_SYSVIEW_GET_INTERRUPT_ID
+ #error "SEGGER_SYSVIEW_GET_INTERRUPT_ID has to be defined in SEGGER_SYSVIEW_Conf.h!"
+#endif
+
+#ifndef SEGGER_SYSVIEW_MAX_ARGUMENTS
+ #define SEGGER_SYSVIEW_MAX_ARGUMENTS 16
+#endif
+
+#ifndef SEGGER_SYSVIEW_MAX_STRING_LEN
+ #define SEGGER_SYSVIEW_MAX_STRING_LEN 128
+#endif
+
+// Use a static buffer instead of a buffer on the stack for packets
+#ifndef SEGGER_SYSVIEW_USE_STATIC_BUFFER
+ #define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1
+#endif
+
+// Maximum packet size used by SystemView for the static buffer
+#ifndef SEGGER_SYSVIEW_MAX_PACKET_SIZE
+ #define SEGGER_SYSVIEW_MAX_PACKET_SIZE SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32
+#endif
+
+// Use post-mortem analysis instead of real-time analysis
+#ifndef SEGGER_SYSVIEW_POST_MORTEM_MODE
+ #define SEGGER_SYSVIEW_POST_MORTEM_MODE 0
+#endif
+
+// Configure how frequently syncronization is sent
+#ifndef SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT
+ #define SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT 8
+#endif
+
+// Lock SystemView (nestable)
+#ifndef SEGGER_SYSVIEW_LOCK
+ #define SEGGER_SYSVIEW_LOCK() SEGGER_RTT_LOCK()
+#endif
+
+// Unlock SystemView (nestable)
+#ifndef SEGGER_SYSVIEW_UNLOCK
+ #define SEGGER_SYSVIEW_UNLOCK() SEGGER_RTT_UNLOCK()
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*************************** End of file ****************************/
diff --git a/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW_Int.h b/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW_Int.h
index 84d8ad5e2d..b52918c676 100644
--- a/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW_Int.h
+++ b/components/app_trace/sys_view/SEGGER/SEGGER_SYSVIEW_Int.h
@@ -1,110 +1,110 @@
-/*********************************************************************
-* SEGGER Microcontroller GmbH & Co. KG *
-* The Embedded Experts *
-**********************************************************************
-* *
-* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
-* *
-* www.segger.com Support: support@segger.com *
-* *
-**********************************************************************
-* *
-* SEGGER SystemView * Real-time application analysis *
-* *
-**********************************************************************
-* *
-* All rights reserved. *
-* *
-* SEGGER strongly recommends to not make any changes *
-* to or modify the source code of this software in order to stay *
-* compatible with the RTT protocol and J-Link. *
-* *
-* Redistribution and use in source and binary forms, with or *
-* without modification, are permitted provided that the following *
-* conditions are met: *
-* *
-* o Redistributions of source code must retain the above copyright *
-* notice, this list of conditions and the following disclaimer. *
-* *
-* o Redistributions in binary form must reproduce the above *
-* copyright notice, this list of conditions and the following *
-* disclaimer in the documentation and/or other materials provided *
-* with the distribution. *
-* *
-* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
-* nor the names of its contributors may be used to endorse or *
-* promote products derived from this software without specific *
-* prior written permission. *
-* *
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
-* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
-* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
-* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
-* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
-* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
-* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
-* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
-* DAMAGE. *
-* *
-**********************************************************************
-* *
-* SystemView version: V2.42 *
-* *
-**********************************************************************
--------------------------- END-OF-HEADER -----------------------------
-File : SEGGER_SYSVIEW_Int.h
-Purpose : SEGGER SystemView internal header.
-Revision: $Rev: 5626 $
-*/
-
-#ifndef SEGGER_SYSVIEW_INT_H
-#define SEGGER_SYSVIEW_INT_H
-
-/*********************************************************************
-*
-* #include Section
-*
-**********************************************************************
-*/
-
-#include "SEGGER_SYSVIEW.h"
-#include "SEGGER_SYSVIEW_Conf.h"
-#include "SEGGER_SYSVIEW_ConfDefaults.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*********************************************************************
-*
-* Private data types
-*
-**********************************************************************
-*/
-//
-// Commands that Host can send to target
-//
-typedef enum {
- SEGGER_SYSVIEW_COMMAND_ID_START = 1,
- SEGGER_SYSVIEW_COMMAND_ID_STOP,
- SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME,
- SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST,
- SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC,
- SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES,
- SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC,
- // Extended commands: Commands >= 128 have a second parameter
- SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE = 128
-} SEGGER_SYSVIEW_COMMAND_ID;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-/*************************** End of file ****************************/
+/*********************************************************************
+* SEGGER Microcontroller GmbH & Co. KG *
+* The Embedded Experts *
+**********************************************************************
+* *
+* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
+* *
+* www.segger.com Support: support@segger.com *
+* *
+**********************************************************************
+* *
+* SEGGER SystemView * Real-time application analysis *
+* *
+**********************************************************************
+* *
+* All rights reserved. *
+* *
+* SEGGER strongly recommends to not make any changes *
+* to or modify the source code of this software in order to stay *
+* compatible with the RTT protocol and J-Link. *
+* *
+* Redistribution and use in source and binary forms, with or *
+* without modification, are permitted provided that the following *
+* conditions are met: *
+* *
+* o Redistributions of source code must retain the above copyright *
+* notice, this list of conditions and the following disclaimer. *
+* *
+* o Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the following *
+* disclaimer in the documentation and/or other materials provided *
+* with the distribution. *
+* *
+* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
+* nor the names of its contributors may be used to endorse or *
+* promote products derived from this software without specific *
+* prior written permission. *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
+* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
+* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
+* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
+* DAMAGE. *
+* *
+**********************************************************************
+* *
+* SystemView version: V2.42 *
+* *
+**********************************************************************
+-------------------------- END-OF-HEADER -----------------------------
+File : SEGGER_SYSVIEW_Int.h
+Purpose : SEGGER SystemView internal header.
+Revision: $Rev: 5626 $
+*/
+
+#ifndef SEGGER_SYSVIEW_INT_H
+#define SEGGER_SYSVIEW_INT_H
+
+/*********************************************************************
+*
+* #include Section
+*
+**********************************************************************
+*/
+
+#include "SEGGER_SYSVIEW.h"
+#include "SEGGER_SYSVIEW_Conf.h"
+#include "SEGGER_SYSVIEW_ConfDefaults.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*********************************************************************
+*
+* Private data types
+*
+**********************************************************************
+*/
+//
+// Commands that Host can send to target
+//
+typedef enum {
+ SEGGER_SYSVIEW_COMMAND_ID_START = 1,
+ SEGGER_SYSVIEW_COMMAND_ID_STOP,
+ SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME,
+ SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST,
+ SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC,
+ SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES,
+ SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC,
+ // Extended commands: Commands >= 128 have a second parameter
+ SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE = 128
+} SEGGER_SYSVIEW_COMMAND_ID;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*************************** End of file ****************************/
diff --git a/components/app_trace/sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.c b/components/app_trace/sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.c
index 803fdc7880..6b55c4f565 100644
--- a/components/app_trace/sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.c
+++ b/components/app_trace/sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.c
@@ -1,290 +1,290 @@
-/*********************************************************************
-* SEGGER Microcontroller GmbH & Co. KG *
-* The Embedded Experts *
-**********************************************************************
-* *
-* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
-* *
-* www.segger.com Support: support@segger.com *
-* *
-**********************************************************************
-* *
-* SEGGER SystemView * Real-time application analysis *
-* *
-**********************************************************************
-* *
-* All rights reserved. *
-* *
-* SEGGER strongly recommends to not make any changes *
-* to or modify the source code of this software in order to stay *
-* compatible with the RTT protocol and J-Link. *
-* *
-* Redistribution and use in source and binary forms, with or *
-* without modification, are permitted provided that the following *
-* conditions are met: *
-* *
-* o Redistributions of source code must retain the above copyright *
-* notice, this list of conditions and the following disclaimer. *
-* *
-* o Redistributions in binary form must reproduce the above *
-* copyright notice, this list of conditions and the following *
-* disclaimer in the documentation and/or other materials provided *
-* with the distribution. *
-* *
-* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
-* nor the names of its contributors may be used to endorse or *
-* promote products derived from this software without specific *
-* prior written permission. *
-* *
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
-* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
-* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
-* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
-* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
-* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
-* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
-* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
-* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
-* DAMAGE. *
-* *
-**********************************************************************
-* *
-* SystemView version: V2.42 *
-* *
-**********************************************************************
--------------------------- END-OF-HEADER -----------------------------
-
-File : SEGGER_SYSVIEW_FreeRTOS.c
-Purpose : Interface between FreeRTOS and SystemView.
-Revision: $Rev: 3734 $
-*/
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-#include "SEGGER_SYSVIEW.h"
-#include "SEGGER_SYSVIEW_FreeRTOS.h"
-#include "string.h" // Required for memset
-
-
-
-typedef struct SYSVIEW_FREERTOS_TASK_STATUS SYSVIEW_FREERTOS_TASK_STATUS;
-
-struct SYSVIEW_FREERTOS_TASK_STATUS {
- U32 xHandle;
- const char* pcTaskName;
- unsigned uxCurrentPriority;
- U32 pxStack;
- unsigned uStackHighWaterMark;
-};
-
-static SYSVIEW_FREERTOS_TASK_STATUS _aTasks[SYSVIEW_FREERTOS_MAX_NOF_TASKS];
-
-/*********************************************************************
-*
-* _cbSendTaskList()
-*
-* Function description
-* This function is part of the link between FreeRTOS and SYSVIEW.
-* Called from SystemView when asked by the host, it uses SYSVIEW
-* functions to send the entire task list to the host.
-*/
-static void _cbSendTaskList(void) {
- unsigned n;
-
- for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
- if (_aTasks[n].xHandle) {
-#if INCLUDE_uxTaskGetStackHighWaterMark // Report Task Stack High Watermark
- _aTasks[n].uStackHighWaterMark = uxTaskGetStackHighWaterMark((TaskHandle_t)_aTasks[n].xHandle);
-#endif
- SYSVIEW_SendTaskInfo((U32)_aTasks[n].xHandle, _aTasks[n].pcTaskName, (unsigned)_aTasks[n].uxCurrentPriority, (U32)_aTasks[n].pxStack, (unsigned)_aTasks[n].uStackHighWaterMark);
- }
- }
-}
-
-/*********************************************************************
-*
-* _cbGetTime()
-*
-* Function description
-* This function is part of the link between FreeRTOS and SYSVIEW.
-* Called from SystemView when asked by the host, returns the
-* current system time in micro seconds.
-*/
-static U64 _cbGetTime(void) {
- U64 Time;
-
- Time = xTaskGetTickCountFromISR();
- Time *= portTICK_PERIOD_MS;
- Time *= 1000;
- return Time;
-}
-
-/*********************************************************************
-*
-* Global functions
-*
-**********************************************************************
-*/
-/*********************************************************************
-*
-* SYSVIEW_AddTask()
-*
-* Function description
-* Add a task to the internal list and record its information.
-*/
-void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
- unsigned n;
-
- if (memcmp(pcTaskName, "IDLE", 5) == 0) {
- return;
- }
-
- for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
- if (_aTasks[n].xHandle == 0) {
- break;
- }
- }
- if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
- SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not record task information. Maximum number of tasks reached.");
- return;
- }
-
- _aTasks[n].xHandle = xHandle;
- _aTasks[n].pcTaskName = pcTaskName;
- _aTasks[n].uxCurrentPriority = uxCurrentPriority;
- _aTasks[n].pxStack = pxStack;
- _aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
-
- SYSVIEW_SendTaskInfo(xHandle, pcTaskName,uxCurrentPriority, pxStack, uStackHighWaterMark);
-
-}
-
-/*********************************************************************
-*
-* SYSVIEW_UpdateTask()
-*
-* Function description
-* Update a task in the internal list and record its information.
-*/
-void SYSVIEW_UpdateTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
- unsigned n;
-
- if (memcmp(pcTaskName, "IDLE", 5) == 0) {
- return;
- }
-
- for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
- if (_aTasks[n].xHandle == xHandle) {
- break;
- }
- }
- if (n < SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
- _aTasks[n].pcTaskName = pcTaskName;
- _aTasks[n].uxCurrentPriority = uxCurrentPriority;
- _aTasks[n].pxStack = pxStack;
- _aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
-
- SYSVIEW_SendTaskInfo(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
- } else {
- SYSVIEW_AddTask(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
- }
-}
-
-/*********************************************************************
-*
-* SYSVIEW_DeleteTask()
-*
-* Function description
-* Delete a task from the internal list.
-*/
-void SYSVIEW_DeleteTask(U32 xHandle) {
- unsigned n;
-
- for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
- if (_aTasks[n].xHandle == xHandle) {
- break;
- }
- }
- if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
- SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not find task information. Cannot delete task.");
- return;
- }
-
- _aTasks[n].xHandle = 0;
-}
-
-/*********************************************************************
-*
-* SYSVIEW_SendTaskInfo()
-*
-* Function description
-* Record task information.
-*/
-void SYSVIEW_SendTaskInfo(U32 TaskID, const char* sName, unsigned Prio, U32 StackBase, unsigned StackSize) {
- SEGGER_SYSVIEW_TASKINFO TaskInfo;
-
- memset(&TaskInfo, 0, sizeof(TaskInfo)); // Fill all elements with 0 to allow extending the structure in future version without breaking the code
- TaskInfo.TaskID = TaskID;
- TaskInfo.sName = sName;
- TaskInfo.Prio = Prio;
- TaskInfo.StackBase = StackBase;
- TaskInfo.StackSize = StackSize;
- SEGGER_SYSVIEW_SendTaskInfo(&TaskInfo);
-}
-
-/*********************************************************************
-*
-* SYSVIEW_RecordU32x4()
-*
-* Function description
-* Record an event with 4 parameters
-*/
-void SYSVIEW_RecordU32x4(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3) {
- U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32];
- U8* pPayload;
- //
- pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
- pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
- pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
- pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
- pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
- //
- SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
-}
-
-/*********************************************************************
-*
-* SYSVIEW_RecordU32x5()
-*
-* Function description
-* Record an event with 5 parameters
-*/
-void SYSVIEW_RecordU32x5(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) {
- U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32];
- U8* pPayload;
- //
- pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
- pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
- pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
- pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
- pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
- pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para4); // Add the fifth parameter to the packet
- //
- SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
-}
-
-/*********************************************************************
-*
-* Public API structures
-*
-**********************************************************************
-*/
-// Callbacks provided to SYSTEMVIEW by FreeRTOS
-const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
- _cbGetTime,
- _cbSendTaskList,
-};
-
-/*************************** End of file ****************************/
+/*********************************************************************
+* SEGGER Microcontroller GmbH & Co. KG *
+* The Embedded Experts *
+**********************************************************************
+* *
+* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
+* *
+* www.segger.com Support: support@segger.com *
+* *
+**********************************************************************
+* *
+* SEGGER SystemView * Real-time application analysis *
+* *
+**********************************************************************
+* *
+* All rights reserved. *
+* *
+* SEGGER strongly recommends to not make any changes *
+* to or modify the source code of this software in order to stay *
+* compatible with the RTT protocol and J-Link. *
+* *
+* Redistribution and use in source and binary forms, with or *
+* without modification, are permitted provided that the following *
+* conditions are met: *
+* *
+* o Redistributions of source code must retain the above copyright *
+* notice, this list of conditions and the following disclaimer. *
+* *
+* o Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the following *
+* disclaimer in the documentation and/or other materials provided *
+* with the distribution. *
+* *
+* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
+* nor the names of its contributors may be used to endorse or *
+* promote products derived from this software without specific *
+* prior written permission. *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
+* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
+* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
+* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
+* DAMAGE. *
+* *
+**********************************************************************
+* *
+* SystemView version: V2.42 *
+* *
+**********************************************************************
+-------------------------- END-OF-HEADER -----------------------------
+
+File : SEGGER_SYSVIEW_FreeRTOS.c
+Purpose : Interface between FreeRTOS and SystemView.
+Revision: $Rev: 3734 $
+*/
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "SEGGER_SYSVIEW.h"
+#include "SEGGER_SYSVIEW_FreeRTOS.h"
+#include "string.h" // Required for memset
+
+
+
+typedef struct SYSVIEW_FREERTOS_TASK_STATUS SYSVIEW_FREERTOS_TASK_STATUS;
+
+struct SYSVIEW_FREERTOS_TASK_STATUS {
+ U32 xHandle;
+ const char* pcTaskName;
+ unsigned uxCurrentPriority;
+ U32 pxStack;
+ unsigned uStackHighWaterMark;
+};
+
+static SYSVIEW_FREERTOS_TASK_STATUS _aTasks[SYSVIEW_FREERTOS_MAX_NOF_TASKS];
+
+/*********************************************************************
+*
+* _cbSendTaskList()
+*
+* Function description
+* This function is part of the link between FreeRTOS and SYSVIEW.
+* Called from SystemView when asked by the host, it uses SYSVIEW
+* functions to send the entire task list to the host.
+*/
+static void _cbSendTaskList(void) {
+ unsigned n;
+
+ for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
+ if (_aTasks[n].xHandle) {
+#if INCLUDE_uxTaskGetStackHighWaterMark // Report Task Stack High Watermark
+ _aTasks[n].uStackHighWaterMark = uxTaskGetStackHighWaterMark((TaskHandle_t)_aTasks[n].xHandle);
+#endif
+ SYSVIEW_SendTaskInfo((U32)_aTasks[n].xHandle, _aTasks[n].pcTaskName, (unsigned)_aTasks[n].uxCurrentPriority, (U32)_aTasks[n].pxStack, (unsigned)_aTasks[n].uStackHighWaterMark);
+ }
+ }
+}
+
+/*********************************************************************
+*
+* _cbGetTime()
+*
+* Function description
+* This function is part of the link between FreeRTOS and SYSVIEW.
+* Called from SystemView when asked by the host, returns the
+* current system time in micro seconds.
+*/
+static U64 _cbGetTime(void) {
+ U64 Time;
+
+ Time = xTaskGetTickCountFromISR();
+ Time *= portTICK_PERIOD_MS;
+ Time *= 1000;
+ return Time;
+}
+
+/*********************************************************************
+*
+* Global functions
+*
+**********************************************************************
+*/
+/*********************************************************************
+*
+* SYSVIEW_AddTask()
+*
+* Function description
+* Add a task to the internal list and record its information.
+*/
+void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
+ unsigned n;
+
+ if (memcmp(pcTaskName, "IDLE", 5) == 0) {
+ return;
+ }
+
+ for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
+ if (_aTasks[n].xHandle == 0) {
+ break;
+ }
+ }
+ if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
+ SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not record task information. Maximum number of tasks reached.");
+ return;
+ }
+
+ _aTasks[n].xHandle = xHandle;
+ _aTasks[n].pcTaskName = pcTaskName;
+ _aTasks[n].uxCurrentPriority = uxCurrentPriority;
+ _aTasks[n].pxStack = pxStack;
+ _aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
+
+ SYSVIEW_SendTaskInfo(xHandle, pcTaskName,uxCurrentPriority, pxStack, uStackHighWaterMark);
+
+}
+
+/*********************************************************************
+*
+* SYSVIEW_UpdateTask()
+*
+* Function description
+* Update a task in the internal list and record its information.
+*/
+void SYSVIEW_UpdateTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
+ unsigned n;
+
+ if (memcmp(pcTaskName, "IDLE", 5) == 0) {
+ return;
+ }
+
+ for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
+ if (_aTasks[n].xHandle == xHandle) {
+ break;
+ }
+ }
+ if (n < SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
+ _aTasks[n].pcTaskName = pcTaskName;
+ _aTasks[n].uxCurrentPriority = uxCurrentPriority;
+ _aTasks[n].pxStack = pxStack;
+ _aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
+
+ SYSVIEW_SendTaskInfo(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
+ } else {
+ SYSVIEW_AddTask(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
+ }
+}
+
+/*********************************************************************
+*
+* SYSVIEW_DeleteTask()
+*
+* Function description
+* Delete a task from the internal list.
+*/
+void SYSVIEW_DeleteTask(U32 xHandle) {
+ unsigned n;
+
+ for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
+ if (_aTasks[n].xHandle == xHandle) {
+ break;
+ }
+ }
+ if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
+ SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not find task information. Cannot delete task.");
+ return;
+ }
+
+ _aTasks[n].xHandle = 0;
+}
+
+/*********************************************************************
+*
+* SYSVIEW_SendTaskInfo()
+*
+* Function description
+* Record task information.
+*/
+void SYSVIEW_SendTaskInfo(U32 TaskID, const char* sName, unsigned Prio, U32 StackBase, unsigned StackSize) {
+ SEGGER_SYSVIEW_TASKINFO TaskInfo;
+
+ memset(&TaskInfo, 0, sizeof(TaskInfo)); // Fill all elements with 0 to allow extending the structure in future version without breaking the code
+ TaskInfo.TaskID = TaskID;
+ TaskInfo.sName = sName;
+ TaskInfo.Prio = Prio;
+ TaskInfo.StackBase = StackBase;
+ TaskInfo.StackSize = StackSize;
+ SEGGER_SYSVIEW_SendTaskInfo(&TaskInfo);
+}
+
+/*********************************************************************
+*
+* SYSVIEW_RecordU32x4()
+*
+* Function description
+* Record an event with 4 parameters
+*/
+void SYSVIEW_RecordU32x4(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3) {
+ U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32];
+ U8* pPayload;
+ //
+ pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
+ pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
+ pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
+ pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
+ pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
+ //
+ SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
+}
+
+/*********************************************************************
+*
+* SYSVIEW_RecordU32x5()
+*
+* Function description
+* Record an event with 5 parameters
+*/
+void SYSVIEW_RecordU32x5(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) {
+ U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32];
+ U8* pPayload;
+ //
+ pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
+ pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
+ pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
+ pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
+ pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
+ pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para4); // Add the fifth parameter to the packet
+ //
+ SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
+}
+
+/*********************************************************************
+*
+* Public API structures
+*
+**********************************************************************
+*/
+// Callbacks provided to SYSTEMVIEW by FreeRTOS
+const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
+ _cbGetTime,
+ _cbSendTaskList,
+};
+
+/*************************** End of file ****************************/
diff --git a/components/app_trace/sys_view/esp32/SEGGER_RTT_esp32.c b/components/app_trace/sys_view/esp32/SEGGER_RTT_esp32.c
index c8b199540e..0cb92be55c 100644
--- a/components/app_trace/sys_view/esp32/SEGGER_RTT_esp32.c
+++ b/components/app_trace/sys_view/esp32/SEGGER_RTT_esp32.c
@@ -20,7 +20,6 @@
#include "rom/ets_sys.h"
#include "esp_app_trace.h"
-#define LOG_LOCAL_LEVEL ESP_LOG_ERROR
#include "esp_log.h"
const static char *TAG = "segger_rtt";
@@ -125,7 +124,7 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
uint8_t event_id = *pbuf;
if (NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
- ESP_LOGE(TAG, "Too large event %d bytes!", NumBytes);
+ ESP_LOGE(TAG, "Too large event %u bytes!", NumBytes);
return 0;
}
if (xPortGetCoreID()) { // dual core specific code
diff --git a/components/app_update/Makefile.projbuild b/components/app_update/Makefile.projbuild
new file mode 100644
index 0000000000..29d223dc5e
--- /dev/null
+++ b/components/app_update/Makefile.projbuild
@@ -0,0 +1,27 @@
+#
+# Generate partition binary
+#
+.PHONY: erase_ota blank_ota_data
+
+GEN_EMPTY_PART := $(PYTHON) $(COMPONENT_PATH)/gen_empty_partition.py
+BLANK_OTA_DATA_FILE = $(BUILD_DIR_BASE)/ota_data_initial.bin
+
+# If there is no otadata partition, both OTA_DATA_OFFSET and BLANK_OTA_DATA_FILE
+# expand to empty values.
+ESPTOOL_ALL_FLASH_ARGS += $(OTA_DATA_OFFSET) $(BLANK_OTA_DATA_FILE)
+
+$(BLANK_OTA_DATA_FILE): partition_table_get_info
+ $(GEN_EMPTY_PART) --size $(OTA_DATA_SIZE) $(BLANK_OTA_DATA_FILE)
+ $(eval BLANK_OTA_DATA_FILE = $(shell if [ $(OTA_DATA_SIZE) != 0 ]; then echo $(BLANK_OTA_DATA_FILE); else echo " "; fi) )
+
+blank_ota_data: $(BLANK_OTA_DATA_FILE)
+
+erase_ota: partition_table_get_info
+ @echo $(if $(OTA_DATA_OFFSET), "Erase ota_data [addr=$(OTA_DATA_OFFSET) size=$(OTA_DATA_SIZE)] ...", $(error "ERROR: Partition table does not have ota_data partition."))
+ $(ESPTOOLPY_SERIAL) erase_region $(OTA_DATA_OFFSET) $(OTA_DATA_SIZE)
+
+all: blank_ota_data
+flash: blank_ota_data
+
+clean:
+ rm -f $(BLANK_OTA_DATA_FILE)
diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c
index 1047d2117f..7a7c9ae648 100644
--- a/components/app_update/esp_ota_ops.c
+++ b/components/app_update/esp_ota_ops.c
@@ -236,19 +236,11 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle)
.size = it->part->size,
};
- if (esp_image_load(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
+ if (esp_image_verify(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
ret = ESP_ERR_OTA_VALIDATE_FAILED;
goto cleanup;
}
-#ifdef CONFIG_SECURE_BOOT_ENABLED
- ret = esp_secure_boot_verify_signature(it->part->address, data.image_len);
- if (ret != ESP_OK) {
- ret = ESP_ERR_OTA_VALIDATE_FAILED;
- goto cleanup;
- }
-#endif
-
cleanup:
LIST_REMOVE(it, entries);
free(it);
@@ -381,7 +373,7 @@ esp_err_t esp_ota_set_boot_partition(const esp_partition_t *partition)
.offset = partition->address,
.size = partition->size,
};
- if (esp_image_load(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
+ if (esp_image_verify(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
return ESP_ERR_OTA_VALIDATE_FAILED;
}
diff --git a/components/app_update/gen_empty_partition.py b/components/app_update/gen_empty_partition.py
new file mode 100755
index 0000000000..f51df22403
--- /dev/null
+++ b/components/app_update/gen_empty_partition.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+#
+# generates an empty binary file
+#
+# This tool generates an empty binary file of the required size.
+#
+# Copyright 2018 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.
+from __future__ import print_function, division
+import argparse
+import os
+import re
+import struct
+import sys
+import hashlib
+import binascii
+
+__version__ = '1.0'
+
+quiet = False
+
+def status(msg):
+ """ Print status message to stderr """
+ if not quiet:
+ critical(msg)
+
+def critical(msg):
+ """ Print critical message to stderr """
+ if not quiet:
+ sys.stderr.write(msg)
+ sys.stderr.write('\n')
+
+def generate_blanked_file(size, output_path):
+ output = ""
+ for i in range(size):
+ output += b"\xFF"
+ try:
+ stdout_binary = sys.stdout.buffer # Python 3
+ except AttributeError:
+ stdout_binary = sys.stdout
+ with stdout_binary if output_path == '-' else open(output_path, 'wb') as f:
+ f.write(output)
+
+def main():
+ global quiet
+ parser = argparse.ArgumentParser(description='Generates an empty binary file of the required size.')
+
+ parser.add_argument('--quiet', '-q', help="Don't print status messages to stderr", action='store_true')
+
+ parser.add_argument('--size', help='Size of generated the file', type=str, required=True)
+
+ parser.add_argument('output', help='Path for binary file.', nargs='?', default='-')
+ args = parser.parse_args()
+
+ quiet = args.quiet
+
+ size = int(args.size, 0)
+ if size > 0 :
+ generate_blanked_file(size, args.output)
+ return 0
+
+class InputError(RuntimeError):
+ def __init__(self, e):
+ super(InputError, self).__init__(e)
+
+if __name__ == '__main__':
+ try:
+ r = main()
+ sys.exit(r)
+ except InputError as e:
+ print(e, file=sys.stderr)
+ sys.exit(2)
diff --git a/components/app_update/include/esp_ota_ops.h b/components/app_update/include/esp_ota_ops.h
index 8fcf622d37..ca77b54226 100644
--- a/components/app_update/include/esp_ota_ops.h
+++ b/components/app_update/include/esp_ota_ops.h
@@ -132,7 +132,7 @@ esp_err_t esp_ota_set_boot_partition(const esp_partition_t* partition);
* If the OTA data partition is not present or not valid then the result is the first app partition found in the
* partition table. In priority order, this means: the factory app, the first OTA app slot, or the test app partition.
*
- * Note that there is no guarantee the returned partition is a valid app. Use esp_image_load(ESP_IMAGE_VERIFY, ...) to verify if the
+ * Note that there is no guarantee the returned partition is a valid app. Use esp_image_verify(ESP_IMAGE_VERIFY, ...) to verify if the
* returned partition contains a bootable image.
*
* @return Pointer to info for partition structure, or NULL if partition table is invalid or a flash read operation failed. Any returned pointer is valid for the lifetime of the application.
diff --git a/components/asio/CMakeLists.txt b/components/asio/CMakeLists.txt
new file mode 100644
index 0000000000..9be66380e7
--- /dev/null
+++ b/components/asio/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(COMPONENT_ADD_INCLUDEDIRS asio/asio/include port/include)
+set(COMPONENT_SRCDIRS asio/asio/src)
+
+set(COMPONENT_SRCEXCLUDE asio/asio/src/asio_ssl.cpp)
+
+set(COMPONENT_REQUIRES lwip)
+
+register_component()
diff --git a/components/asio/asio b/components/asio/asio
new file mode 160000
index 0000000000..55efc179b7
--- /dev/null
+++ b/components/asio/asio
@@ -0,0 +1 @@
+Subproject commit 55efc179b76139c8f9b44bf22a4aba4803f7a7bd
diff --git a/components/asio/component.mk b/components/asio/component.mk
new file mode 100644
index 0000000000..e024df3f31
--- /dev/null
+++ b/components/asio/component.mk
@@ -0,0 +1,6 @@
+COMPONENT_ADD_INCLUDEDIRS := asio/asio/include port/include
+COMPONENT_PRIV_INCLUDEDIRS := private_include
+COMPONENT_SRCDIRS := asio/asio/src
+COMPONENT_OBJEXCLUDE := asio/asio/src/asio_ssl.o
+
+COMPONENT_SUBMODULES += asio
diff --git a/components/asio/port/include/esp_asio_config.h b/components/asio/port/include/esp_asio_config.h
new file mode 100644
index 0000000000..accccad0da
--- /dev/null
+++ b/components/asio/port/include/esp_asio_config.h
@@ -0,0 +1,45 @@
+// Copyright 2018 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.
+#ifndef _ESP_ASIO_CONFIG_H_
+#define _ESP_ASIO_CONFIG_H_
+
+//
+// Enabling exceptions only when they are enabled in menuconfig
+//
+# include
+# ifndef CONFIG_CXX_EXCEPTIONS
+# define ASIO_NO_EXCEPTIONS
+# endif // CONFIG_CXX_EXCEPTIONS
+
+//
+// LWIP compatifility inet and address macros/functions
+//
+# define LWIP_COMPAT_SOCKET_INET 1
+# define LWIP_COMPAT_SOCKET_ADDR 1
+
+//
+// Specific ASIO feature flags
+//
+# define ASIO_DISABLE_SERIAL_PORT
+# define ASIO_SEPARATE_COMPILATION
+# define ASIO_STANDALONE
+# define ASIO_NO_TYPEID
+# define ASIO_DISABLE_SIGNAL
+# define ASIO_HAS_PTHREADS
+# define ASIO_DISABLE_EPOLL
+# define ASIO_DISABLE_EVENTFD
+# define ASIO_DISABLE_SIGNAL
+# define ASIO_DISABLE_SIGACTION
+
+#endif // _ESP_ASIO_CONFIG_H_
diff --git a/components/asio/port/include/esp_exception.h b/components/asio/port/include/esp_exception.h
new file mode 100644
index 0000000000..3c5c043755
--- /dev/null
+++ b/components/asio/port/include/esp_exception.h
@@ -0,0 +1,39 @@
+
+// Copyright 2018 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.
+#ifndef _ESP_EXCEPTION_H_
+#define _ESP_EXCEPTION_H_
+
+//
+// This exception stub is enabled only if exceptions are disabled in menuconfig
+//
+#if !defined(CONFIG_CXX_EXCEPTIONS) && defined (ASIO_NO_EXCEPTIONS)
+
+#include "esp_log.h"
+
+//
+// asio exception stub
+//
+namespace asio {
+namespace detail {
+template
+void throw_exception(const Exception& e)
+{
+ ESP_LOGE("esp32_asio_exception", "Caught exception: %s!", e.what());
+ abort();
+}
+}}
+#endif // CONFIG_CXX_EXCEPTIONS==1 && defined (ASIO_NO_EXCEPTIONS)
+
+#endif // _ESP_EXCEPTION_H_
diff --git a/components/aws_iot/aws-iot-device-sdk-embedded-C b/components/aws_iot/aws-iot-device-sdk-embedded-C
index 8bf852db77..299183238f 160000
--- a/components/aws_iot/aws-iot-device-sdk-embedded-C
+++ b/components/aws_iot/aws-iot-device-sdk-embedded-C
@@ -1 +1 @@
-Subproject commit 8bf852db77c360eebfa4b800754fdb90e29ea43e
+Subproject commit 299183238ffe7a3e6a5ca0af9db19c10eaca62cf
diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild
index f5394dc274..75dae508ae 100644
--- a/components/bootloader/Kconfig.projbuild
+++ b/components/bootloader/Kconfig.projbuild
@@ -142,7 +142,7 @@ config SECURE_BOOT_ENABLED
When enabling secure boot, JTAG and ROM BASIC Interpreter are permanently disabled by default.
- Refer to https://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling.
+ Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
choice SECURE_BOOTLOADER_MODE
bool "Secure bootloader mode"
@@ -206,7 +206,7 @@ config SECURE_BOOT_VERIFICATION_KEY
PEM formatted private key using the espsecure.py
extract_public_key command.
- Refer to https://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling.
+ Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
config SECURE_BOOT_INSECURE
bool "Allow potentially insecure options"
@@ -217,7 +217,7 @@ config SECURE_BOOT_INSECURE
Only enable these options if you are very sure.
- Refer to https://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling.
+ Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
config FLASH_ENCRYPTION_ENABLED
bool "Enable flash encryption on boot (READ DOCS FIRST)"
@@ -228,7 +228,7 @@ config FLASH_ENCRYPTION_ENABLED
Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted
system is complicated and not always possible.
- Read https://esp-idf.readthedocs.io/en/latest/security/flash-encryption.html before enabling.
+ Read https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html before enabling.
config FLASH_ENCRYPTION_INSECURE
bool "Allow potentially insecure options"
@@ -275,6 +275,13 @@ config SECURE_BOOT_ALLOW_JTAG
Only set this option in testing environments.
+config SECURE_BOOT_ALLOW_SHORT_APP_PARTITION
+ bool "Allow app partition length not 64KB aligned"
+ depends on SECURE_BOOT_INSECURE
+ help
+ If not set (default), app partition size must be a multiple of 64KB. App images are padded to 64KB length, and the bootloader checks any trailing bytes after the signature (before the next 64KB boundary) have not been written. This is because flash cache maps entire 64KB pages into the address space. This prevents an attacker from appending unverified data after the app image in the flash, causing it to be mapped into the address space.
+
+ Setting this option allows the app partition length to be unaligned, and disables padding of the app image to this length. It is generally not recommended to set this option, unless you have a legacy partitioning scheme which doesn't support 64KB aligned partition lengths.
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_ENCRYPT
bool "Leave UART bootloader encryption enabled"
diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild
index 7876635cc9..b283c90445 100644
--- a/components/bootloader/Makefile.projbuild
+++ b/components/bootloader/Makefile.projbuild
@@ -32,7 +32,8 @@ BOOTLOADER_MAKE= +\
V=$(V) \
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
TEST_COMPONENTS= \
- TESTS_ALL=
+ TESTS_ALL= \
+ EXCLUDE_COMPONENTS=
.PHONY: bootloader-clean bootloader-flash bootloader-list-components bootloader $(BOOTLOADER_BIN)
@@ -106,7 +107,7 @@ bootloader: $(BOOTLOADER_DIGEST_BIN)
$(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOTLOADER_KEY)
@echo "DIGEST $(notdir $@)"
- $(Q) $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOTLOADER_KEY) -o $@ $<
+ $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOTLOADER_KEY) -o $@ $<
else # CONFIG_SECURE_BOOT_ENABLED && !CONFIG_SECURE_BOOTLOADER_REFLASHABLE && !CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH
bootloader:
@@ -115,7 +116,7 @@ bootloader:
endif
ifndef CONFIG_SECURE_BOOT_ENABLED
-# don't build bootloader by default is secure boot is enabled
+# don't build bootloader by default if secure boot is enabled
all_binaries: $(BOOTLOADER_BIN)
endif
diff --git a/components/bootloader/subproject/CMakeLists.txt b/components/bootloader/subproject/CMakeLists.txt
index 228bd89914..7a34d8ea22 100644
--- a/components/bootloader/subproject/CMakeLists.txt
+++ b/components/bootloader/subproject/CMakeLists.txt
@@ -10,7 +10,7 @@ if(NOT IDF_PATH)
"in by the parent build process.")
endif()
-set(COMPONENTS bootloader esptool_py esp32 soc bootloader_support log spi_flash micro-ecc soc)
+set(COMPONENTS bootloader esptool_py esp32 partition_table soc bootloader_support log spi_flash micro-ecc soc)
set(BOOTLOADER_BUILD 1)
add_definitions(-DBOOTLOADER_BUILD=1)
diff --git a/components/bootloader/subproject/main/bootloader_start.c b/components/bootloader/subproject/main/bootloader_start.c
index 64af8268e4..6f7edc42ee 100644
--- a/components/bootloader/subproject/main/bootloader_start.c
+++ b/components/bootloader/subproject/main/bootloader_start.c
@@ -27,51 +27,42 @@
static const char* TAG = "boot";
-static esp_err_t select_image (esp_image_metadata_t *image_data);
+static int select_partition_number (bootloader_state_t *bs);
static int selected_boot_partition(const bootloader_state_t *bs);
/*
* We arrive here after the ROM bootloader finished loading this second stage bootloader from flash.
* The hardware is mostly uninitialized, flash cache is down and the app CPU is in reset.
* We do have a stack, so we can do the initialization in C.
*/
-void call_start_cpu0()
+void __attribute__((noreturn)) call_start_cpu0()
{
// 1. Hardware initialization
- if(bootloader_init() != ESP_OK){
- return;
+ if (bootloader_init() != ESP_OK) {
+ bootloader_reset();
}
- // 2. Select image to boot
- esp_image_metadata_t image_data;
- if(select_image(&image_data) != ESP_OK){
- return;
- }
-
- // 3. Loading the selected image
- bootloader_utility_load_image(&image_data);
-}
-
-// Selects image to boot
-static esp_err_t select_image (esp_image_metadata_t *image_data)
-{
- // 1. Load partition table
+ // 2. Select the number of boot partition
bootloader_state_t bs = { 0 };
- if (!bootloader_utility_load_partition_table(&bs)) {
- ESP_LOGE(TAG, "load partition table error!");
- return ESP_FAIL;
- }
-
- // 2. Select boot partition
- int boot_index = selected_boot_partition(&bs);
- if(boot_index == INVALID_INDEX) {
- return ESP_FAIL; // Unrecoverable failure (not due to corrupt ota data or bad partition contents)
+ int boot_index = select_partition_number(&bs);
+ if (boot_index == INVALID_INDEX) {
+ bootloader_reset();
}
// 3. Load the app image for booting
- if (!bootloader_utility_load_boot_image(&bs, boot_index, image_data)) {
- return ESP_FAIL;
+ bootloader_utility_load_boot_image(&bs, boot_index);
+}
+
+// Select the number of boot partition
+static int select_partition_number (bootloader_state_t *bs)
+{
+ // 1. Load partition table
+ if (!bootloader_utility_load_partition_table(bs)) {
+ ESP_LOGE(TAG, "load partition table error!");
+ return INVALID_INDEX;
}
- return ESP_OK;
+
+ // 2. Select the number of boot partition
+ return selected_boot_partition(bs);
}
/*
diff --git a/components/bootloader/subproject/main/esp32.bootloader.ld b/components/bootloader/subproject/main/esp32.bootloader.ld
index 54fe1a9a3c..d44295115e 100644
--- a/components/bootloader/subproject/main/esp32.bootloader.ld
+++ b/components/bootloader/subproject/main/esp32.bootloader.ld
@@ -8,12 +8,19 @@ Linker file used to link the bootloader.
The main purpose is to make sure the bootloader can load into main memory
without overwriting itself.
*/
+
MEMORY
{
/* I/O */
dport0_seg (RW) : org = 0x3FF00000, len = 0x10
- /* IRAM POOL1, used for APP CPU cache. We can abuse it in bootloader because APP CPU is still held in reset, the main app enables APP CPU cache */
- iram_seg (RWX) : org = 0x40078000, len = 0x8000
+ /* IRAM POOL1, used for APP CPU cache. Bootloader runs from here during the final stage of loading the app because APP CPU is still held in reset, the main app enables APP CPU cache */
+ iram_loader_seg (RWX) : org = 0x40078000, len = 0x8000 /* 32KB, APP CPU cache */
+ /* 63kB, IRAM. We skip the first 1k to prevent the entry point being
+ placed into the same range as exception vectors in the app.
+ This leads to idf_monitor decoding ROM bootloader "entry 0x40080xxx"
+ message as one of the exception vectors, which looks scary to users.
+ */
+ iram_seg (RWX) : org = 0x40080400, len = 0xfc00
/* 64k at the end of DRAM, after ROM bootloader stack */
dram_seg (RW) : org = 0x3FFF0000, len = 0x10000
}
@@ -24,7 +31,36 @@ ENTRY(call_start_cpu0);
SECTIONS
{
- .iram1.text :
+
+ .iram_loader.text :
+ {
+ . = ALIGN (16);
+ _stext = .;
+ _text_start = ABSOLUTE(.);
+ *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
+ *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
+ *liblog.a:(.literal .text .literal.* .text.*)
+ *libgcc.a:(.literal .text .literal.* .text.*)
+ *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)
+ *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*)
+ *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*)
+ *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
+ *libbootloader_support.a:efuse.*(.literal .text .literal.* .text.*)
+ *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
+ *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
+ *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
+ *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*)
+ *libbootloader_support.a:secure_boot_signatures.*(.literal .text .literal.* .text.*)
+ *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*)
+ *libspi_flash.a:*.*(.literal .text .literal.* .text.*)
+ *(.fini.literal)
+ *(.fini)
+ *(.gnu.version)
+ _text_end = ABSOLUTE(.);
+ _etext = .;
+ } > iram_loader_seg
+
+ .iram.text :
{
. = ALIGN (16);
*(.entry.text)
@@ -88,13 +124,13 @@ SECTIONS
. = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */
__init_array_start = ABSOLUTE(.);
- KEEP (*crtbegin.o(.ctors))
- KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*crtbegin.*(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__init_array_end = ABSOLUTE(.);
- KEEP (*crtbegin.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*crtbegin.*(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* C++ exception handlers table: */
@@ -121,7 +157,7 @@ SECTIONS
_stext = .;
_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
- *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
+ *(.iram .iram.*) /* catch stray IRAM_ATTR */
*(.fini.literal)
*(.fini)
*(.gnu.version)
diff --git a/components/bootloader_support/CMakeLists.txt b/components/bootloader_support/CMakeLists.txt
index 21978397e8..bc610eb960 100644
--- a/components/bootloader_support/CMakeLists.txt
+++ b/components/bootloader_support/CMakeLists.txt
@@ -1,12 +1,12 @@
set(COMPONENT_SRCDIRS "src")
if(${BOOTLOADER_BUILD})
- set(COMPONENT_ADD_INCLUDEDIRS "include include_priv")
+ set(COMPONENT_ADD_INCLUDEDIRS "include include_bootloader")
set(COMPONENT_REQUIRES)
set(COMPONENT_PRIV_REQUIRES spi_flash micro-ecc)
else()
set(COMPONENT_ADD_INCLUDEDIRS "include")
- set(COMPONENT_PRIV_INCLUDEDIRS "include_priv")
+ set(COMPONENT_PRIV_INCLUDEDIRS "include_bootloader")
set(COMPONENT_REQUIRES)
set(COMPONENT_PRIV_REQUIRES spi_flash mbedtls micro-ecc)
endif()
diff --git a/components/bootloader_support/component.mk b/components/bootloader_support/component.mk
index 6db815afff..8907c31ae0 100644
--- a/components/bootloader_support/component.mk
+++ b/components/bootloader_support/component.mk
@@ -1,10 +1,10 @@
COMPONENT_ADD_INCLUDEDIRS := include
-COMPONENT_PRIV_INCLUDEDIRS := include_priv
ifdef IS_BOOTLOADER_BUILD
-# share "private" headers with the bootloader component
-# eventual goal: all functionality that needs this lives in bootloader_support
-COMPONENT_ADD_INCLUDEDIRS += include_priv
+# share "include_bootloader" headers with bootloader main component
+COMPONENT_ADD_INCLUDEDIRS += include_bootloader
+else
+COMPONENT_PRIV_INCLUDEDIRS := include_bootloader
endif
COMPONENT_SRCDIRS := src
diff --git a/components/bootloader_support/include/bootloader_common.h b/components/bootloader_support/include/bootloader_common.h
index 07fc9341c5..d5a92cc79b 100644
--- a/components/bootloader_support/include/bootloader_common.h
+++ b/components/bootloader_support/include/bootloader_common.h
@@ -68,3 +68,26 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat
* @return Returns true if the list contains the label, false otherwise.
*/
bool bootloader_common_label_search(const char *list, char *label);
+
+/**
+ * @brief Calculates a sha-256 for a given partition or returns a appended digest.
+ *
+ * This function can be used to return the SHA-256 digest of application, bootloader and data partitions.
+ * For apps with SHA-256 appended to the app image, the result is the appended SHA-256 value for the app image content.
+ * The hash is verified before returning, if app content is invalid then the function returns ESP_ERR_IMAGE_INVALID.
+ * For apps without SHA-256 appended to the image, the result is the SHA-256 of all bytes in the app image.
+ * For other partition types, the result is the SHA-256 of the entire partition.
+ *
+ * @param[in] address Address of partition.
+ * @param[in] size Size of partition.
+ * @param[in] type Type of partition. For applications the type is 0, otherwise type is data.
+ * @param[out] out_sha_256 Returned SHA-256 digest for a given partition.
+ *
+ * @return
+ * - ESP_OK: In case of successful operation.
+ * - ESP_ERR_INVALID_ARG: The size was 0 or the sha_256 was NULL.
+ * - ESP_ERR_NO_MEM: Cannot allocate memory for sha256 operation.
+ * - ESP_ERR_IMAGE_INVALID: App partition doesn't contain a valid app image.
+ * - ESP_FAIL: An allocation error occurred.
+ */
+esp_err_t bootloader_common_get_sha256_of_partition(uint32_t address, uint32_t size, int type, uint8_t *out_sha_256);
diff --git a/components/bootloader_support/include/esp_flash_partitions.h b/components/bootloader_support/include/esp_flash_partitions.h
index 843e5a283c..b5f37aa5fc 100644
--- a/components/bootloader_support/include/esp_flash_partitions.h
+++ b/components/bootloader_support/include/esp_flash_partitions.h
@@ -17,17 +17,17 @@
#include "esp_err.h"
#include "esp_flash_data_types.h"
#include
+#include "sdkconfig.h"
/* Pre-partition table fixed flash offsets */
#define ESP_BOOTLOADER_DIGEST_OFFSET 0x0
#define ESP_BOOTLOADER_OFFSET 0x1000 /* Offset of bootloader image. Has matching value in bootloader KConfig.projbuild file. */
-#define ESP_BOOTLOADER_SIZE (ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET)
-#define ESP_PARTITION_TABLE_OFFSET 0x8000 /* Offset of partition table. Has matching value in partition_table Kconfig.projbuild file. */
+#define ESP_PARTITION_TABLE_OFFSET CONFIG_PARTITION_TABLE_OFFSET /* Offset of partition table. Backwards-compatible name.*/
#define ESP_PARTITION_TABLE_MAX_LEN 0xC00 /* Maximum length of partition table data */
#define ESP_PARTITION_TABLE_MAX_ENTRIES (ESP_PARTITION_TABLE_MAX_LEN / sizeof(esp_partition_info_t)) /* Maximum length of partition table data, including terminating entry */
-/* @brief Verify the partition table (does not include verifying secure boot cryptographic signature)
+/* @brief Verify the partition table
*
* @param partition_table Pointer to at least ESP_PARTITION_TABLE_MAX_ENTRIES of potential partition table data. (ESP_PARTITION_TABLE_MAX_LEN bytes.)
* @param log_errors Log errors if the partition table is invalid.
@@ -35,6 +35,13 @@
*
* @return ESP_OK on success, ESP_ERR_INVALID_STATE if partition table is not valid.
*/
-esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions);
+esp_err_t esp_partition_table_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions);
+
+
+/* This function is included for compatibility with the ESP-IDF v3.x API */
+inline static __attribute__((deprecated)) esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
+{
+ return esp_partition_table_verify(partition_table, log_errors, num_partitions);
+}
#endif
diff --git a/components/bootloader_support/include/esp_image_format.h b/components/bootloader_support/include/esp_image_format.h
index d2dcfd312c..6d92a35b00 100644
--- a/components/bootloader_support/include/esp_image_format.h
+++ b/components/bootloader_support/include/esp_image_format.h
@@ -36,7 +36,7 @@ typedef enum {
} esp_image_spi_mode_t;
/* SPI flash clock frequency */
-enum {
+typedef enum {
ESP_IMAGE_SPI_SPEED_40M,
ESP_IMAGE_SPI_SPEED_26M,
ESP_IMAGE_SPI_SPEED_20M,
@@ -96,11 +96,12 @@ typedef struct {
esp_image_segment_header_t segments[ESP_IMAGE_MAX_SEGMENTS]; /* Per-segment header data */
uint32_t segment_data[ESP_IMAGE_MAX_SEGMENTS]; /* Data offsets for each segment */
uint32_t image_len; /* Length of image on flash, in bytes */
+ uint8_t image_digest[32]; /* appended SHA-256 digest */
} esp_image_metadata_t;
/* Mode selection for esp_image_load() */
typedef enum {
- ESP_IMAGE_VERIFY, /* Verify image contents, load metadata. Print errorsors. */
+ ESP_IMAGE_VERIFY, /* Verify image contents, load metadata. Print errors. */
ESP_IMAGE_VERIFY_SILENT, /* Verify image contents, load metadata. Don't print errors. */
#ifdef BOOTLOADER_BUILD
ESP_IMAGE_LOAD, /* Verify image contents, load to memory. Print errors. */
@@ -110,6 +111,11 @@ typedef enum {
/**
* @brief Verify and (optionally, in bootloader mode) load an app image.
*
+ * This name is deprecated and is included for compatibility with the ESP-IDF v3.x API.
+ * It will be removed in V4.0 version.
+ * Function has been renamed to esp_image_verify().
+ * Use function esp_image_verify() to verify a image. And use function bootloader_load_image() to load image from a bootloader space.
+ *
* If encryption is enabled, data will be transparently decrypted.
*
* @param mode Mode of operation (verify, silent verify, or load).
@@ -130,7 +136,60 @@ typedef enum {
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
*/
-esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data);
+esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data) __attribute__((deprecated));
+
+/**
+ * @brief Verify an app image.
+ *
+ * If encryption is enabled, data will be transparently decrypted.
+ *
+ * @param mode Mode of operation (verify, silent verify, or load).
+ * @param part Partition to load the app from.
+ * @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
+ * 'start_addr' member should be set (to the start address of the image.)
+ * Other fields will all be initialised by this function.
+ *
+ * Image validation checks:
+ * - Magic byte.
+ * - Partition smaller than 16MB.
+ * - All segments & image fit in partition.
+ * - 8 bit image checksum is valid.
+ * - SHA-256 of image is valid (if image has this appended).
+ * - (Signature) if signature verification is enabled.
+ *
+ * @return
+ * - ESP_OK if verify or load was successful
+ * - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
+ * - ESP_ERR_IMAGE_INVALID if the image appears invalid.
+ * - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
+ */
+esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data);
+
+/**
+ * @brief Verify and load an app image (available only in space of bootloader).
+ *
+ * If encryption is enabled, data will be transparently decrypted.
+ *
+ * @param part Partition to load the app from.
+ * @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
+ * 'start_addr' member should be set (to the start address of the image.)
+ * Other fields will all be initialised by this function.
+ *
+ * Image validation checks:
+ * - Magic byte.
+ * - Partition smaller than 16MB.
+ * - All segments & image fit in partition.
+ * - 8 bit image checksum is valid.
+ * - SHA-256 of image is valid (if image has this appended).
+ * - (Signature) if signature verification is enabled.
+ *
+ * @return
+ * - ESP_OK if verify or load was successful
+ * - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
+ * - ESP_ERR_IMAGE_INVALID if the image appears invalid.
+ * - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
+ */
+esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data);
/**
* @brief Verify the bootloader image.
diff --git a/components/bootloader_support/include_priv/bootloader_config.h b/components/bootloader_support/include_bootloader/bootloader_config.h
similarity index 100%
rename from components/bootloader_support/include_priv/bootloader_config.h
rename to components/bootloader_support/include_bootloader/bootloader_config.h
diff --git a/components/bootloader_support/include_priv/bootloader_flash.h b/components/bootloader_support/include_bootloader/bootloader_flash.h
similarity index 100%
rename from components/bootloader_support/include_priv/bootloader_flash.h
rename to components/bootloader_support/include_bootloader/bootloader_flash.h
diff --git a/components/bootloader_support/include_priv/bootloader_init.h b/components/bootloader_support/include_bootloader/bootloader_init.h
similarity index 100%
rename from components/bootloader_support/include_priv/bootloader_init.h
rename to components/bootloader_support/include_bootloader/bootloader_init.h
diff --git a/components/bootloader_support/include_priv/bootloader_random.h b/components/bootloader_support/include_bootloader/bootloader_random.h
similarity index 100%
rename from components/bootloader_support/include_priv/bootloader_random.h
rename to components/bootloader_support/include_bootloader/bootloader_random.h
diff --git a/components/bootloader_support/include_priv/bootloader_sha.h b/components/bootloader_support/include_bootloader/bootloader_sha.h
similarity index 61%
rename from components/bootloader_support/include_priv/bootloader_sha.h
rename to components/bootloader_support/include_bootloader/bootloader_sha.h
index 38bd080485..079a457917 100644
--- a/components/bootloader_support/include_priv/bootloader_sha.h
+++ b/components/bootloader_support/include_bootloader/bootloader_sha.h
@@ -22,6 +22,7 @@
#include
#include
+#include "esp_err.h"
typedef void *bootloader_sha256_handle_t;
@@ -30,3 +31,26 @@ bootloader_sha256_handle_t bootloader_sha256_start();
void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len);
void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest);
+
+/**
+ * @brief Converts an array to a printable string.
+ *
+ * This function is useful for printing SHA-256 digest.
+ * \code{c}
+ * // Example of using. image_hash will be printed
+ * #define HASH_LEN 32 // SHA-256 digest length
+ * ...
+ * char hash_print[HASH_LEN * 2 + 1];
+ * hash_print[HASH_LEN * 2] = 0;
+ * bootloader_sha256_hex_to_str(hash_print, image_hash, HASH_LEN);
+ * ESP_LOGI(TAG, %s", hash_print);
+ * \endcode
+
+ * @param[out] out_str Output string
+ * @param[in] in_array_hex Pointer to input array
+ * @param[in] len Length of input array
+ *
+ * @return ESP_OK: Successful
+ * ESP_ERR_INVALID_ARG: Error in the passed arguments
+ */
+esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len);
diff --git a/components/bootloader_support/include_priv/bootloader_utility.h b/components/bootloader_support/include_bootloader/bootloader_utility.h
similarity index 79%
rename from components/bootloader_support/include_priv/bootloader_utility.h
rename to components/bootloader_support/include_bootloader/bootloader_utility.h
index 6cf6a77e1a..31213a0160 100644
--- a/components/bootloader_support/include_priv/bootloader_utility.h
+++ b/components/bootloader_support/include_bootloader/bootloader_utility.h
@@ -40,25 +40,25 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs);
int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs);
/**
- * @brief Load the app image for booting.
+ * @brief Load the selected partition and start application.
*
* Start from partition 'start_index', if not bootable then work backwards to FACTORY_INDEX
* (ie try any OTA slots in descending order and then the factory partition).
* If still nothing, start from 'start_index + 1' and work up to highest numbered OTA partition.
* If still nothing, try TEST_APP_INDEX.
+ * Everything this function calls must be located in the iram_loader_seg segment.
*
* @param[in] bs Bootloader state structure.
* @param[in] start_index The index from which the search for images begins.
- * @param[out] result The image found.
- * @return Returns true on success, false if there's no bootable app in the partition table.
*/
-bool bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index, esp_image_metadata_t *result);
+__attribute__((noreturn)) void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index);
+
/**
- * @brief Loading the selected image.
+ * @brief Software reset the ESP32
*
- * Copy loaded segments to RAM, set up caches for mapped segments, and start application.
+ * Bootloader code should call this in the case that it cannot proceed.
*
- * @param[in] data Structure to hold on-flash image metadata.
+ * It is not recommended to call this function from an app (if called, the app will abort).
*/
-void bootloader_utility_load_image(const esp_image_metadata_t* image_data);
+__attribute__((noreturn)) void bootloader_reset(void);
diff --git a/components/bootloader_support/include_priv/flash_qio_mode.h b/components/bootloader_support/include_bootloader/flash_qio_mode.h
similarity index 100%
rename from components/bootloader_support/include_priv/flash_qio_mode.h
rename to components/bootloader_support/include_bootloader/flash_qio_mode.h
diff --git a/components/bootloader_support/src/bootloader_common.c b/components/bootloader_support/src/bootloader_common.c
index 0d72c3e119..a174926012 100644
--- a/components/bootloader_support/src/bootloader_common.c
+++ b/components/bootloader_support/src/bootloader_common.c
@@ -26,6 +26,11 @@
#include "esp_flash_partitions.h"
#include "bootloader_flash.h"
#include "bootloader_common.h"
+#include "soc/gpio_periph.h"
+#include "esp_image_format.h"
+#include "bootloader_sha.h"
+
+#define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */
static const char* TAG = "boot_comm";
@@ -42,6 +47,9 @@ bool bootloader_common_ota_select_valid(const esp_ota_select_entry_t *s)
esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio(uint32_t num_pin, uint32_t delay_sec)
{
gpio_pad_select_gpio(num_pin);
+ if (GPIO_PIN_MUX_REG[num_pin]) {
+ PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[num_pin]);
+ }
gpio_pad_pullup(num_pin);
uint32_t tm_start = esp_log_early_timestamp();
if (GPIO_INPUT_GET(num_pin) == 1) {
@@ -96,26 +104,14 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat
int num_partitions;
bool ret = true;
-#ifdef CONFIG_SECURE_BOOT_ENABLED
- if (esp_secure_boot_enabled()) {
- ESP_LOGI(TAG, "Verifying partition table signature...");
- err = esp_secure_boot_verify_signature(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_MAX_LEN);
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "Failed to verify partition table signature.");
- return false;
- }
- ESP_LOGD(TAG, "Partition table signature verified");
- }
-#endif
-
- partitions = bootloader_mmap(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_MAX_LEN);
+ partitions = bootloader_mmap(ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN);
if (!partitions) {
- ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_MAX_LEN);
+ ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN);
return false;
}
- ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_ADDR, (intptr_t)partitions);
+ ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_OFFSET, (intptr_t)partitions);
- err = esp_partition_table_basic_verify(partitions, true, &num_partitions);
+ err = esp_partition_table_verify(partitions, true, &num_partitions);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to verify partition table");
ret = false;
@@ -130,7 +126,7 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat
fl_ota_data_erase = true;
}
// partition->label is not null-terminated string.
- strncpy(label, (char *)&partition->label, sizeof(partition->label));
+ strncpy(label, (char *)&partition->label, sizeof(label) - 1);
if (fl_ota_data_erase == true || (bootloader_common_label_search(list_erase, label) == true)) {
err = esp_rom_spiflash_erase_area(partition->pos.offset, partition->pos.size);
if (err != ESP_OK) {
@@ -153,3 +149,46 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat
return ret;
}
+
+esp_err_t bootloader_common_get_sha256_of_partition (uint32_t address, uint32_t size, int type, uint8_t *out_sha_256)
+{
+ if (out_sha_256 == NULL || size == 0) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ if (type == PART_TYPE_APP) {
+ const esp_partition_pos_t partition_pos = {
+ .offset = address,
+ .size = size,
+ };
+ esp_image_metadata_t data;
+ // Function esp_image_verify() verifies and fills the structure data.
+ // here important to get: image_digest, image_len, hash_appended.
+ if (esp_image_verify(ESP_IMAGE_VERIFY_SILENT, &partition_pos, &data) != ESP_OK) {
+ return ESP_ERR_IMAGE_INVALID;
+ }
+ if (data.image.hash_appended) {
+ memcpy(out_sha_256, data.image_digest, ESP_PARTITION_HASH_LEN);
+ return ESP_OK;
+ }
+ // If image doesn't have a appended hash then hash calculates for entire image.
+ size = data.image_len;
+ }
+ // If image is type by data then hash is calculated for entire image.
+ const void *partition_bin = bootloader_mmap(address, size);
+ if (partition_bin == NULL) {
+ ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", address, size);
+ return ESP_FAIL;
+ }
+ bootloader_sha256_handle_t sha_handle = bootloader_sha256_start();
+ if (sha_handle == NULL) {
+ bootloader_munmap(partition_bin);
+ return ESP_ERR_NO_MEM;
+ }
+ bootloader_sha256_data(sha_handle, partition_bin, size);
+ bootloader_sha256_finish(sha_handle, out_sha_256);
+
+ bootloader_munmap(partition_bin);
+
+ return ESP_OK;
+}
diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c
index 73a7995625..fe0d756fb5 100644
--- a/components/bootloader_support/src/bootloader_init.c
+++ b/components/bootloader_support/src/bootloader_init.c
@@ -39,6 +39,7 @@
#include "soc/timer_group_reg.h"
#include "soc/gpio_reg.h"
#include "soc/gpio_sig_map.h"
+#include "soc/rtc_wdt.h"
#include "sdkconfig.h"
#include "esp_image_format.h"
@@ -143,7 +144,7 @@ static esp_err_t bootloader_main()
ets_set_appcpu_boot_addr(0);
/* disable watch dog here */
- REG_CLR_BIT( RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN );
+ rtc_wdt_disable();
REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
diff --git a/components/bootloader_support/src/bootloader_sha.c b/components/bootloader_support/src/bootloader_sha.c
index be23f7f26a..1f7c1b4934 100644
--- a/components/bootloader_support/src/bootloader_sha.c
+++ b/components/bootloader_support/src/bootloader_sha.c
@@ -28,7 +28,10 @@ bootloader_sha256_handle_t bootloader_sha256_start()
return NULL;
}
mbedtls_sha256_init(ctx);
- assert(mbedtls_sha256_starts_ret(ctx, false) == 0);
+ int ret = mbedtls_sha256_starts_ret(ctx, false);
+ if (ret != 0) {
+ return NULL;
+ }
return ctx;
}
@@ -36,7 +39,8 @@ void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data,
{
assert(handle != NULL);
mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)handle;
- assert(mbedtls_sha256_update_ret(ctx, data, data_len) == 0);
+ int ret = mbedtls_sha256_update_ret(ctx, data, data_len);
+ assert(ret == 0);
}
void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest)
@@ -44,7 +48,8 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest
assert(handle != NULL);
mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)handle;
if (digest != NULL) {
- assert(mbedtls_sha256_finish_ret(ctx, digest) == 0);
+ int ret = mbedtls_sha256_finish_ret(ctx, digest);
+ assert(ret == 0);
}
mbedtls_sha256_free(ctx);
free(handle);
@@ -164,3 +169,21 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest
}
#endif
+
+esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len)
+{
+ if (out_str == NULL || in_array_hex == NULL || len == 0) {
+ return ESP_ERR_INVALID_ARG;
+ }
+ for (int i = 0; i < len; i++) {
+ for (int shift = 0; shift < 2; shift++) {
+ uint8_t nibble = (in_array_hex[i] >> (shift ? 0 : 4)) & 0x0F;
+ if (nibble < 10) {
+ out_str[i*2+shift] = '0' + nibble;
+ } else {
+ out_str[i*2+shift] = 'a' + nibble - 10;
+ }
+ }
+ }
+ return ESP_OK;
+}
diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c
index eeaee21798..5550945bb6 100644
--- a/components/bootloader_support/src/bootloader_utility.c
+++ b/components/bootloader_support/src/bootloader_utility.c
@@ -49,12 +49,15 @@
#include "bootloader_random.h"
#include "bootloader_config.h"
#include "bootloader_common.h"
+#include "bootloader_utility.h"
+#include "bootloader_sha.h"
static const char* TAG = "boot";
/* Reduce literal size for some generic string literals */
#define MAP_ERR_MSG "Image contains multiple %s segments. Only the last one will be mapped."
+static void load_image(const esp_image_metadata_t* image_data);
static void unpack_load_app(const esp_image_metadata_t *data);
static void set_cache_and_start_app(uint32_t drom_addr,
uint32_t drom_load_addr,
@@ -71,26 +74,14 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs)
esp_err_t err;
int num_partitions;
-#ifdef CONFIG_SECURE_BOOT_ENABLED
- if(esp_secure_boot_enabled()) {
- ESP_LOGI(TAG, "Verifying partition table signature...");
- err = esp_secure_boot_verify_signature(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_MAX_LEN);
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "Failed to verify partition table signature.");
- return false;
- }
- ESP_LOGD(TAG, "Partition table signature verified");
- }
-#endif
-
- partitions = bootloader_mmap(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_MAX_LEN);
+ partitions = bootloader_mmap(ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN);
if (!partitions) {
- ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_MAX_LEN);
- return false;
+ ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN);
+ return false;
}
- ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_ADDR, (intptr_t)partitions);
+ ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_OFFSET, (intptr_t)partitions);
- err = esp_partition_table_basic_verify(partitions, true, &num_partitions);
+ err = esp_partition_table_verify(partitions, true, &num_partitions);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to verify partition table");
return false;
@@ -221,8 +212,8 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
bootloader_munmap(ota_select_map);
ESP_LOGD(TAG, "OTA sequence values A 0x%08x B 0x%08x", sa.ota_seq, sb.ota_seq);
- if(sa.ota_seq == UINT32_MAX && sb.ota_seq == UINT32_MAX) {
- ESP_LOGD(TAG, "OTA sequence numbers both empty (all-0xFF)");
+ if ((sa.ota_seq == UINT32_MAX && sb.ota_seq == UINT32_MAX) || (bs->app_count == 0)) {
+ ESP_LOGD(TAG, "OTA sequence numbers both empty (all-0xFF) or partition table does not have bootable ota_apps (app_count=%d)", bs->app_count);
if (bs->factory.offset != 0) {
ESP_LOGI(TAG, "Defaulting to factory image");
return FACTORY_INDEX;
@@ -275,7 +266,7 @@ static bool try_load_partition(const esp_partition_pos_t *partition, esp_image_m
return false;
}
#ifdef BOOTLOADER_BUILD
- if (esp_image_load(ESP_IMAGE_LOAD, partition, data) == ESP_OK) {
+ if (bootloader_load_image(partition, data) == ESP_OK) {
ESP_LOGI(TAG, "Loaded app from partition at offset 0x%x",
partition->offset);
return true;
@@ -287,18 +278,21 @@ static bool try_load_partition(const esp_partition_pos_t *partition, esp_image_m
#define TRY_LOG_FORMAT "Trying partition index %d offs 0x%x size 0x%x"
-bool bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index, esp_image_metadata_t *result)
+void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index)
{
int index = start_index;
esp_partition_pos_t part;
+ esp_image_metadata_t image_data;
+
if(start_index == TEST_APP_INDEX) {
- if (try_load_partition(&bs->test, result)) {
- return true;
+ if (try_load_partition(&bs->test, &image_data)) {
+ load_image(&image_data);
} else {
ESP_LOGE(TAG, "No bootable test partition in the partition table");
- return false;
+ bootloader_reset();
}
}
+
/* work backwards from start_index, down to the factory app */
for(index = start_index; index >= FACTORY_INDEX; index--) {
part = index_to_partition(bs, index);
@@ -306,8 +300,8 @@ bool bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
continue;
}
ESP_LOGD(TAG, TRY_LOG_FORMAT, index, part.offset, part.size);
- if (try_load_partition(&part, result)) {
- return true;
+ if (try_load_partition(&part, &image_data)) {
+ load_image(&image_data);
}
log_invalid_app_partition(index);
}
@@ -319,23 +313,24 @@ bool bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
continue;
}
ESP_LOGD(TAG, TRY_LOG_FORMAT, index, part.offset, part.size);
- if (try_load_partition(&part, result)) {
- return true;
+ if (try_load_partition(&part, &image_data)) {
+ load_image(&image_data);
}
log_invalid_app_partition(index);
}
- if (try_load_partition(&bs->test, result)) {
+ if (try_load_partition(&bs->test, &image_data)) {
ESP_LOGW(TAG, "Falling back to test app as only bootable partition");
- return true;
+ load_image(&image_data);
}
ESP_LOGE(TAG, "No bootable app partitions in the partition table");
- bzero(result, sizeof(esp_image_metadata_t));
- return false;
+ bzero(&image_data, sizeof(esp_image_metadata_t));
+ bootloader_reset();
}
-void bootloader_utility_load_image(const esp_image_metadata_t* image_data)
+// Copy loaded segments to RAM, set up caches for mapped segments, and start application.
+static void load_image(const esp_image_metadata_t* image_data)
{
#if defined(CONFIG_SECURE_BOOT_ENABLED) || defined(CONFIG_FLASH_ENCRYPTION_ENABLED)
esp_err_t err;
@@ -368,8 +363,7 @@ void bootloader_utility_load_image(const esp_image_metadata_t* image_data)
so issue a system reset to ensure flash encryption
cache resets properly */
ESP_LOGI(TAG, "Resetting with flash encryption enabled...");
- REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
- return;
+ bootloader_reset();
}
#endif
@@ -463,10 +457,24 @@ static void set_cache_and_start_app(
// Application will need to do Cache_Flush(1) and Cache_Read_Enable(1)
ESP_LOGD(TAG, "start: 0x%08x", entry_addr);
- typedef void (*entry_t)(void);
+ typedef void (*entry_t)(void) __attribute__((noreturn));
entry_t entry = ((entry_t) entry_addr);
// TODO: we have used quite a bit of stack at this point.
// use "movsp" instruction to reset stack back to where ROM stack starts.
(*entry)();
}
+
+
+void bootloader_reset(void)
+{
+#ifdef BOOTLOADER_BUILD
+ uart_tx_flush(0); /* Ensure any buffered log output is displayed */
+ uart_tx_flush(1);
+ ets_delay_us(1000); /* Allow last byte to leave FIFO */
+ REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
+ while (1) { } /* This line will never be reached, used to keep gcc happy */
+#else
+ abort(); /* This function should really not be called from application code */
+#endif
+}
diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c
index 92acf3b025..fea89e6a37 100644
--- a/components/bootloader_support/src/esp_image_format.c
+++ b/components/bootloader_support/src/esp_image_format.c
@@ -75,7 +75,7 @@ static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t
static esp_err_t __attribute__((unused)) verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
static esp_err_t __attribute__((unused)) verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
-esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
+static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
#ifdef BOOTLOADER_BUILD
bool do_load = (mode == ESP_IMAGE_LOAD);
@@ -128,7 +128,7 @@ esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *
err = verify_image_header(data->start_addr, &data->image, silent);
if (err != ESP_OK) {
-goto err;
+ goto err;
}
if (data->image.segment_count > ESP_IMAGE_MAX_SEGMENTS) {
@@ -189,6 +189,17 @@ goto err;
bootloader_sha256_finish(sha_handle, NULL);
}
}
+
+ if (data->image.hash_appended) {
+ const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
+ if (hash == NULL) {
+ err = ESP_FAIL;
+ goto err;
+ }
+ memcpy(data->image_digest, hash, HASH_LEN);
+ bootloader_munmap(hash);
+ }
+
sha_handle = NULL;
if (err != ESP_OK) {
goto err;
@@ -224,6 +235,22 @@ goto err;
return err;
}
+esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data)
+{
+#ifdef BOOTLOADER_BUILD
+ return image_load(ESP_IMAGE_LOAD, part, data);
+#else
+ return ESP_FAIL;
+#endif
+}
+
+esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
+{
+ return image_load(mode, part, data);
+}
+
+esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data) __attribute__((alias("esp_image_verify")));
+
static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent)
{
esp_err_t err = ESP_OK;
@@ -446,7 +473,7 @@ esp_err_t esp_image_verify_bootloader(uint32_t *length)
.offset = ESP_BOOTLOADER_OFFSET,
.size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
};
- esp_err_t err = esp_image_load(ESP_IMAGE_VERIFY,
+ esp_err_t err = esp_image_verify(ESP_IMAGE_VERIFY,
&bootloader_part,
&data);
if (length != NULL) {
@@ -556,18 +583,9 @@ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_i
static void debug_log_hash(const uint8_t *image_hash, const char *label)
{
#if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG
- char hash_print[sizeof(image_hash)*2 + 1];
- hash_print[sizeof(image_hash)*2] = 0;
- for (int i = 0; i < sizeof(image_hash); i++) {
- for (int shift = 0; shift < 2; shift++) {
- uint8_t nibble = (image_hash[i] >> (shift ? 0 : 4)) & 0x0F;
- if (nibble < 10) {
- hash_print[i*2+shift] = '0' + nibble;
- } else {
- hash_print[i*2+shift] = 'a' + nibble - 10;
- }
- }
- }
- ESP_LOGD(TAG, "%s: %s", label, hash_print);
+ char hash_print[HASH_LEN * 2 + 1];
+ hash_print[HASH_LEN * 2] = 0;
+ bootloader_sha256_hex_to_str(hash_print, image_hash, HASH_LEN);
+ ESP_LOGD(TAG, "%s: %s", label, hash_print);
#endif
}
diff --git a/components/bootloader_support/src/flash_encrypt.c b/components/bootloader_support/src/flash_encrypt.c
index 290a02a911..2b229c00b7 100644
--- a/components/bootloader_support/src/flash_encrypt.c
+++ b/components/bootloader_support/src/flash_encrypt.c
@@ -254,7 +254,7 @@ static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partitio
ESP_LOGE(TAG, "Failed to read partition table data");
return err;
}
- if (esp_partition_table_basic_verify(partition_table, false, num_partitions) == ESP_OK) {
+ if (esp_partition_table_verify(partition_table, false, num_partitions) == ESP_OK) {
ESP_LOGD(TAG, "partition table is plaintext. Encrypting...");
esp_err_t err = esp_flash_encrypt_region(ESP_PARTITION_TABLE_OFFSET,
FLASH_SECTOR_SIZE);
@@ -281,7 +281,7 @@ static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partit
if (partition->type == PART_TYPE_APP) {
/* check if the partition holds a valid unencrypted app */
esp_image_metadata_t data_ignored;
- err = esp_image_load(ESP_IMAGE_VERIFY,
+ err = esp_image_verify(ESP_IMAGE_VERIFY,
&partition->pos,
&data_ignored);
should_encrypt = (err == ESP_OK);
diff --git a/components/bootloader_support/src/flash_partitions.c b/components/bootloader_support/src/flash_partitions.c
index f8a24f26c2..6686457338 100644
--- a/components/bootloader_support/src/flash_partitions.c
+++ b/components/bootloader_support/src/flash_partitions.c
@@ -20,7 +20,7 @@
static const char *TAG = "flash_parts";
-esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
+esp_err_t esp_partition_table_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
{
int md5_found = 0;
int num_parts;
diff --git a/components/bootloader_support/src/flash_qio_mode.c b/components/bootloader_support/src/flash_qio_mode.c
index 361e3d4ada..f7a0b414d7 100644
--- a/components/bootloader_support/src/flash_qio_mode.c
+++ b/components/bootloader_support/src/flash_qio_mode.c
@@ -35,6 +35,7 @@
#define CMD_WRDI 0x04
#define CMD_RDSR 0x05
#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */
+#define CMD_OTPEN 0x3A /* Enable OTP mode, not all SPI flash uses this command */
static const char *TAG = "qio_mode";
@@ -65,6 +66,11 @@ static void write_status_8b_wrsr2(unsigned new_status);
/* Write 16 bit status using WRSR */
static void write_status_16b_wrsr(unsigned new_status);
+/* Read 8 bit status of XM25QU64A */
+static unsigned read_status_8b_xmc25qu64a();
+/* Write 8 bit status of XM25QU64A */
+static void write_status_8b_xmc25qu64a(unsigned new_status);
+
#define ESP32_D2WD_WP_GPIO 7 /* ESP32-D2WD has this GPIO wired to WP pin of flash */
#ifndef CONFIG_BOOTLOADER_SPI_WP_PIN // Set in menuconfig if SPI flasher config is set to a quad mode
@@ -84,11 +90,12 @@ static void write_status_16b_wrsr(unsigned new_status);
Searching of this table stops when the first match is found.
*/
const static qio_info_t chip_data[] = {
-/* Manufacturer, mfg_id, flash_id, id mask, Read Status, Write Status, QIE Bit */
- { "MXIC", 0xC2, 0x2000, 0xFF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 },
- { "ISSI", 0x9D, 0x4000, 0xCF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 }, /* IDs 0x40xx, 0x70xx */
- { "WinBond", 0xEF, 0x4000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 },
- { "GD", 0xC8, 0x6000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 },
+/* Manufacturer, mfg_id, flash_id, id mask, Read Status, Write Status, QIE Bit */
+ { "MXIC", 0xC2, 0x2000, 0xFF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 },
+ { "ISSI", 0x9D, 0x4000, 0xCF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 }, /* IDs 0x40xx, 0x70xx */
+ { "WinBond", 0xEF, 0x4000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 },
+ { "GD", 0xC8, 0x6000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 },
+ { "XM25QU64A", 0x20, 0x3817, 0xFFFF, read_status_8b_xmc25qu64a, write_status_8b_xmc25qu64a, 6 },
/* Final entry is default entry, if no other IDs have matched.
@@ -96,7 +103,7 @@ const static qio_info_t chip_data[] = {
GigaDevice (mfg ID 0xC8, flash IDs including 4016),
FM25Q32 (QOUT mode only, mfg ID 0xA1, flash IDs including 4016)
*/
- { NULL, 0xFF, 0xFFFF, 0xFFFF, read_status_8b_rdsr2, write_status_8b_wrsr2, 1 },
+ { NULL, 0xFF, 0xFFFF, 0xFFFF, read_status_8b_rdsr2, write_status_8b_wrsr2, 1 },
};
#define NUM_CHIPS (sizeof(chip_data) / sizeof(qio_info_t))
@@ -246,6 +253,24 @@ static void write_status_16b_wrsr(unsigned new_status)
execute_flash_command(CMD_WRSR, new_status, 16, 0);
}
+static unsigned read_status_8b_xmc25qu64a()
+{
+ execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */
+ esp_rom_spiflash_wait_idle(&g_rom_flashchip);
+ uint32_t read_status = execute_flash_command(CMD_RDSR, 0, 0, 8);
+ execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */
+ return read_status;
+}
+
+static void write_status_8b_xmc25qu64a(unsigned new_status)
+{
+ execute_flash_command(CMD_OTPEN, 0, 0, 0); /* Enter OTP mode */
+ esp_rom_spiflash_wait_idle(&g_rom_flashchip);
+ execute_flash_command(CMD_WRSR, new_status, 8, 0);
+ esp_rom_spiflash_wait_idle(&g_rom_flashchip);
+ execute_flash_command(CMD_WRDI, 0, 0, 0); /* Exit OTP mode */
+}
+
static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
{
uint32_t old_ctrl_reg = SPIFLASH.ctrl.val;
diff --git a/components/bootloader_support/src/secure_boot_signatures.c b/components/bootloader_support/src/secure_boot_signatures.c
index 988ab7935f..ddb7ad73a6 100644
--- a/components/bootloader_support/src/secure_boot_signatures.c
+++ b/components/bootloader_support/src/secure_boot_signatures.c
@@ -84,10 +84,13 @@ esp_err_t esp_secure_boot_verify_signature_block(const esp_secure_boot_sig_block
return ESP_FAIL;
}
+ ESP_LOGD(TAG, "Verifying secure boot signature");
+
is_valid = uECC_verify(signature_verification_key_start,
image_digest,
DIGEST_LEN,
sig_block->signature,
uECC_secp256r1());
+ ESP_LOGD(TAG, "Verification result %d", is_valid);
return is_valid ? ESP_OK : ESP_ERR_IMAGE_INVALID;
}
diff --git a/components/bootloader_support/test/test_verify_image.c b/components/bootloader_support/test/test_verify_image.c
index 7994667f33..153a859c29 100644
--- a/components/bootloader_support/test/test_verify_image.c
+++ b/components/bootloader_support/test/test_verify_image.c
@@ -25,7 +25,7 @@ TEST_CASE("Verify bootloader image in flash", "[bootloader_support]")
.size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
};
esp_image_metadata_t data = { 0 };
- TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_load(ESP_IMAGE_VERIFY, &fake_bootloader_partition, &data));
+ TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_verify(ESP_IMAGE_VERIFY, &fake_bootloader_partition, &data));
TEST_ASSERT_NOT_EQUAL(0, data.image_len);
uint32_t bootloader_length = 0;
@@ -43,7 +43,7 @@ TEST_CASE("Verify unit test app image", "[bootloader_support]")
.size = running->size,
};
- TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_load(ESP_IMAGE_VERIFY, &running_pos, &data));
+ TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_verify(ESP_IMAGE_VERIFY, &running_pos, &data));
TEST_ASSERT_NOT_EQUAL(0, data.image_len);
TEST_ASSERT_TRUE(data.image_len <= running->size);
}
diff --git a/components/bt/Kconfig b/components/bt/Kconfig
index 3074629c7e..187cdd73ce 100644
--- a/components/bt/Kconfig
+++ b/components/bt/Kconfig
@@ -70,7 +70,7 @@ menu "MODEM SLEEP Options"
config BTDM_CONTROLLER_MODEM_SLEEP
bool "Bluetooth modem sleep"
depends on BT_ENABLED
- default y
+ default n
help
Enable/disable bluetooth controller low power mode.
Note that currently there is problem in the combination use of bluetooth modem sleep and Dynamic Frequency Scaling(DFS). So do not enable DFS if bluetooth modem sleep is in use.
@@ -155,6 +155,11 @@ config CLASSIC_BT_ENABLED
help
For now this option needs "SMP_ENABLE" to be set to yes
+config BT_SSP_ENABLE
+ bool "Enable Secure Simple Pairing"
+ depends on CLASSIC_BT_ENABLED
+ default CLASSIC_BT_ENABLED
+
config A2DP_ENABLE
bool "A2DP"
depends on CLASSIC_BT_ENABLED
@@ -220,6 +225,13 @@ config GATTC_ENABLE
help
This option can be close when the app work only on gatt server mode
+config GATTC_CACHE_NVS_FLASH
+ bool "Save gattc cache data to nvs flash"
+ depends on GATTC_ENABLE
+ default n
+ help
+ This select can save gattc cache data to nvs flash
+
config BLE_SMP_ENABLE
bool "Include BLE security module(SMP)"
depends on BLUEDROID_ENABLED
@@ -997,6 +1009,15 @@ config BT_BLE_DYNAMIC_ENV_MEMORY
help
This select can make the allocation of memory will become more flexible
+config BLE_HOST_QUEUE_CONGESTION_CHECK
+ bool "BLE queue congestion check"
+ depends on BLUEDROID_ENABLED
+ default n
+ help
+ When scanning and scan duplicate is not enabled, if there are a lot of adv packets around or application layer
+ handling adv packets is slow, it will cause the controller memory to run out. if enabled, adv packets will be
+ lost when host queue is congested.
+
config BLE_SCAN_DUPLICATE
bool "BLE Scan Duplicate Options"
depends on BLUEDROID_ENABLED
@@ -1007,8 +1028,8 @@ config BLE_SCAN_DUPLICATE
config DUPLICATE_SCAN_CACHE_SIZE
int "Maximum number of devices in scan duplicate filter"
depends on BLE_SCAN_DUPLICATE
- range 10 200
- default 20
+ range 10 1000
+ default 50
help
Maximum number of devices which can be recorded in scan duplicate filter.
When the maximum amount of device in the filter is reached, the cache will be refreshed.
@@ -1023,8 +1044,8 @@ config BLE_MESH_SCAN_DUPLICATE_EN
config MESH_DUPLICATE_SCAN_CACHE_SIZE
int "Maximum number of Mesh adv packets in scan duplicate filter"
depends on BLE_MESH_SCAN_DUPLICATE_EN
- range 10 200
- default 50
+ range 10 1000
+ default 100
help
Maximum number of adv packets which can be recorded in duplicate scan cache for BLE Mesh.
When the maximum amount of device in the filter is reached, the cache will be refreshed.
diff --git a/components/bt/bluedroid/api/esp_gap_bt_api.c b/components/bt/bluedroid/api/esp_gap_bt_api.c
index ebe3d5bfc0..6be94bd0f5 100644
--- a/components/bt/bluedroid/api/esp_gap_bt_api.c
+++ b/components/bt/bluedroid/api/esp_gap_bt_api.c
@@ -240,4 +240,65 @@ esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list)
return (ret == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+#if (BT_SSP_INCLUDED == TRUE)
+esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
+ void *value, uint8_t len)
+{
+ btc_msg_t msg;
+ btc_gap_bt_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BT;
+ msg.act = BTC_GAP_BT_ACT_SET_SECURITY_PARAM;
+ arg.set_security_param.param_type = param_type;
+ arg.set_security_param.len = len;
+ arg.set_security_param.value = value;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey)
+{
+ btc_msg_t msg;
+ btc_gap_bt_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BT;
+ msg.act = BTC_GAP_BT_ACT_PASSKEY_REPLY;
+ arg.passkey_reply.accept = accept;
+ arg.passkey_reply.passkey = passkey;
+ memcpy(arg.passkey_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t));
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
+{
+ btc_msg_t msg;
+ btc_gap_bt_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BT;
+ msg.act = BTC_GAP_BT_ACT_CONFIRM_REPLY;
+ arg.confirm_reply.accept = accept;
+ memcpy(arg.confirm_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t));
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+#endif /*(BT_SSP_INCLUDED == TRUE)*/
+
#endif /* #if BTC_GAP_BT_INCLUDED == TRUE */
diff --git a/components/bt/bluedroid/api/esp_gattc_api.c b/components/bt/bluedroid/api/esp_gattc_api.c
index fc431d6fb4..578916e5f2 100644
--- a/components/bt/bluedroid/api/esp_gattc_api.c
+++ b/components/bt/bluedroid/api/esp_gattc_api.c
@@ -164,6 +164,7 @@ esp_gatt_status_t esp_ble_gattc_get_all_char(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((start_handle == 0) && (end_handle == 0)) {
+ *count = 0;
return ESP_GATT_INVALID_HANDLE;
}
@@ -206,6 +207,7 @@ esp_gatt_status_t esp_ble_gattc_get_char_by_uuid(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (start_handle == 0 && end_handle == 0) {
+ *count = 0;
return ESP_GATT_INVALID_HANDLE;
}
@@ -247,6 +249,7 @@ esp_gatt_status_t esp_ble_gattc_get_descr_by_char_handle(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (char_handle == 0) {
+ *count = 0;
return ESP_GATT_INVALID_HANDLE;
}
@@ -269,6 +272,7 @@ esp_gatt_status_t esp_ble_gattc_get_include_service(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (start_handle == 0 && end_handle == 0) {
+ *count = 0;
return ESP_GATT_INVALID_HANDLE;
}
@@ -291,6 +295,7 @@ esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((start_handle == 0 && end_handle == 0) && (type != ESP_GATT_DB_DESCRIPTOR)) {
+ *count = 0;
return ESP_GATT_INVALID_HANDLE;
}
@@ -308,6 +313,7 @@ esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (start_handle == 0 && end_handle == 0) {
+ *count = 0;
return ESP_GATT_INVALID_HANDLE;
}
diff --git a/components/bt/bluedroid/api/esp_gatts_api.c b/components/bt/bluedroid/api/esp_gatts_api.c
index 8eab2e48c8..d40f2ac09a 100644
--- a/components/bt/bluedroid/api/esp_gatts_api.c
+++ b/components/bt/bluedroid/api/esp_gatts_api.c
@@ -261,7 +261,7 @@ esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, conn_id)) {
- LOG_ERROR("%s, the l2cap chanel is congest.", __func__);
+ LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
return ESP_FAIL;
}
diff --git a/components/bt/bluedroid/api/include/api/esp_gap_bt_api.h b/components/bt/bluedroid/api/include/api/esp_gap_bt_api.h
index d30767e72f..69dc0e4374 100644
--- a/components/bt/bluedroid/api/include/api/esp_gap_bt_api.h
+++ b/components/bt/bluedroid/api/include/api/esp_gap_bt_api.h
@@ -102,6 +102,19 @@ typedef enum {
ESP_BT_COD_SRVC_INFORMATION = 0x400, /*!< Information, e.g., WEB-server, WAP-server */
} esp_bt_cod_srvc_t;
+
+typedef enum {
+ ESP_BT_SP_IOCAP_MODE = 0, /*!< Set IO mode */
+ //ESP_BT_SP_OOB_DATA, //TODO /*!< Set OOB data */
+} esp_bt_sp_param_t;
+
+/* relate to BTM_IO_CAP_xxx in stack/btm_api.h */
+#define ESP_BT_IO_CAP_OUT 0 /*!< DisplayOnly */ /* relate to BTM_IO_CAP_OUT in stack/btm_api.h */
+#define ESP_BT_IO_CAP_IO 1 /*!< DisplayYesNo */ /* relate to BTM_IO_CAP_IO in stack/btm_api.h */
+#define ESP_BT_IO_CAP_IN 2 /*!< KeyboardOnly */ /* relate to BTM_IO_CAP_IN in stack/btm_api.h */
+#define ESP_BT_IO_CAP_NONE 3 /*!< NoInputNoOutput */ /* relate to BTM_IO_CAP_NONE in stack/btm_api.h */
+typedef uint8_t esp_bt_io_cap_t; /*!< combination of the io capability */
+
/// Bits of major service class field
#define ESP_BT_COD_SRVC_BIT_MASK (0xffe000) /*!< Major service bit mask */
#define ESP_BT_COD_SRVC_BIT_OFFSET (13) /*!< Major service bit offset */
@@ -149,6 +162,9 @@ typedef enum {
ESP_BT_GAP_RMT_SRVCS_EVT, /*!< get remote services event */
ESP_BT_GAP_RMT_SRVC_REC_EVT, /*!< get remote service record event */
ESP_BT_GAP_AUTH_CMPL_EVT, /*!< AUTH complete event */
+ ESP_BT_GAP_CFM_REQ_EVT, /*!< Simple Pairing User Confirmation request. */
+ ESP_BT_GAP_KEY_NOTIF_EVT, /*!< Simple Pairing Passkey Notification */
+ ESP_BT_GAP_KEY_REQ_EVT, /*!< Simple Pairing Passkey request */
ESP_BT_GAP_READ_RSSI_DELTA_EVT, /*!< read rssi event */
ESP_BT_GAP_EVT_MAX,
} esp_bt_gap_cb_event_t;
@@ -216,6 +232,29 @@ typedef union {
esp_bt_status_t stat; /*!< authentication complete status */
uint8_t device_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; /*!< device name */
} auth_cmpl; /*!< authentication complete parameter struct */
+
+ /**
+ * @brief ESP_BT_GAP_CFM_REQ_EVT
+ */
+ struct cfm_req_param {
+ esp_bd_addr_t bda; /*!< remote bluetooth device address*/
+ uint32_t num_val; /*!< the numeric value for comparison. */
+ } cfm_req; /*!< confirm request parameter struct */
+
+ /**
+ * @brief ESP_BT_GAP_KEY_NOTIF_EVT
+ */
+ struct key_notif_param {
+ esp_bd_addr_t bda; /*!< remote bluetooth device address*/
+ uint32_t passkey; /*!< the numeric value for passkey entry. */
+ } key_notif; /*!< passkey notif parameter struct */
+
+ /**
+ * @brief ESP_BT_GAP_KEY_REQ_EVT
+ */
+ struct key_req_param {
+ esp_bd_addr_t bda; /*!< remote bluetooth device address*/
+ } key_req; /*!< passkey request parameter struct */
} esp_bt_gap_cb_param_t;
/**
@@ -447,6 +486,53 @@ int esp_bt_gap_get_bond_device_num(void);
*/
esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list);
+#if (BT_SSP_INCLUDED == TRUE)
+/**
+* @brief Set a GAP security parameter value. Overrides the default value.
+*
+* @param[in] param_type : the type of the param which is to be set
+* @param[in] value : the param value
+* @param[in] len : the length of the param value
+*
+* @return - ESP_OK : success
+* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+* - other : failed
+*
+*/
+esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
+ void *value, uint8_t len);
+
+/**
+* @brief Reply the key value to the peer device in the legacy connection stage.
+*
+* @param[in] bd_addr : BD address of the peer
+* @param[in] accept : passkey entry sucessful or declined.
+* @param[in] passkey : passkey value, must be a 6 digit number,
+* can be lead by 0.
+*
+* @return - ESP_OK : success
+* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+* - other : failed
+*
+*/
+esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey);
+
+
+/**
+* @brief Reply the confirm value to the peer device in the legacy connection stage.
+*
+* @param[in] bd_addr : BD address of the peer device
+* @param[in] accept : numbers to compare are the same or different.
+*
+* @return - ESP_OK : success
+* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+* - other : failed
+*
+*/
+esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept);
+
+#endif /*(BT_SSP_INCLUDED == TRUE)*/
+
#ifdef __cplusplus
}
#endif
diff --git a/components/bt/bluedroid/api/include/api/esp_gatt_defs.h b/components/bt/bluedroid/api/include/api/esp_gatt_defs.h
index 77cdcd6526..7053f266f2 100644
--- a/components/bt/bluedroid/api/include/api/esp_gatt_defs.h
+++ b/components/bt/bluedroid/api/include/api/esp_gatt_defs.h
@@ -422,7 +422,7 @@ typedef struct {
* @brief service element
*/
typedef struct {
- bool is_primary; /*!< The service flag, ture if the service is primary service, else is secondly service */
+ bool is_primary; /*!< The service flag, true if the service is primary service, else is secondly service */
uint16_t start_handle; /*!< The start handle of the service */
uint16_t end_handle; /*!< The end handle of the service */
esp_bt_uuid_t uuid; /*!< The uuid of the service */
diff --git a/components/bt/bluedroid/api/include/api/esp_gatts_api.h b/components/bt/bluedroid/api/include/api/esp_gatts_api.h
index bc97b76e46..d25d297806 100644
--- a/components/bt/bluedroid/api/include/api/esp_gatts_api.h
+++ b/components/bt/bluedroid/api/include/api/esp_gatts_api.h
@@ -350,7 +350,8 @@ esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db
uint8_t max_nb_attr,
uint8_t srvc_inst_id);
/**
- * @brief This function is called to add an included service. After included
+ * @brief This function is called to add an included service. This function have to be called between
+ * 'esp_ble_gatts_create_service' and 'esp_ble_gatts_add_char'. After included
* service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT
* is reported the included service ID.
*
diff --git a/components/bt/bluedroid/bta/av/bta_av_aact.c b/components/bt/bluedroid/bta/av/bta_av_aact.c
index 5c0d15de7d..9ac791c6fa 100644
--- a/components/bt/bluedroid/bta/av/bta_av_aact.c
+++ b/components/bt/bluedroid/bta/av/bta_av_aact.c
@@ -815,7 +815,7 @@ void bta_av_role_res (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
if (p_data->role_res.hci_status != HCI_SUCCESS) {
p_scb->role &= ~BTA_AV_ROLE_START_INT;
- bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
+ bta_sys_idle(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
/* start failed because of role switch. */
start.chnl = p_scb->chnl;
start.status = BTA_AV_FAIL_ROLE;
@@ -956,7 +956,7 @@ void bta_av_do_disc_a2d (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
p_scb->sec_mask = p_data->api_open.sec_mask;
p_scb->use_rc = p_data->api_open.use_rc;
- bta_sys_app_open(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
+ bta_sys_app_open(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), p_scb->app_id, p_scb->peer_addr);
/* allocate discovery database */
if (p_scb->p_disc_db == NULL) {
@@ -1330,7 +1330,7 @@ void bta_av_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
L2CA_SetTxPriority(p_scb->l2c_cid, L2CAP_CHNL_PRIORITY_MEDIUM);
L2CA_SetChnlFlushability (p_scb->l2c_cid, TRUE);
- bta_sys_conn_open(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
+ bta_sys_conn_open(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), p_scb->app_id, p_scb->peer_addr);
memset(&p_scb->q_info, 0, sizeof(tBTA_AV_Q_INFO));
p_scb->l2c_bufs = 0;
@@ -1933,8 +1933,7 @@ void bta_av_do_start (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
if ((p_scb->started == FALSE) && ((p_scb->role & BTA_AV_ROLE_START_INT) == 0)) {
p_scb->role |= BTA_AV_ROLE_START_INT;
- bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
-
+ bta_sys_busy(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
AVDT_StartReq(&p_scb->avdt_handle, 1);
} else if (p_scb->started) {
p_scb->role |= BTA_AV_ROLE_START_INT;
@@ -1969,7 +1968,7 @@ void bta_av_str_stopped (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
APPL_TRACE_ERROR("bta_av_str_stopped:audio_open_cnt=%d, p_data %p",
bta_av_cb.audio_open_cnt, p_data);
- bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
+ bta_sys_idle(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 || bta_av_cb.audio_open_cnt == 1) {
policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
}
@@ -2239,7 +2238,7 @@ void bta_av_start_ok (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
if (p_data && (p_data->hdr.offset != BTA_AV_RS_NONE)) {
p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
if (p_data->hdr.offset == BTA_AV_RS_FAIL) {
- bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
+ bta_sys_idle(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
start.chnl = p_scb->chnl;
start.status = BTA_AV_FAIL_ROLE;
start.hndl = p_scb->hndl;
@@ -2275,9 +2274,9 @@ void bta_av_start_ok (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
}
/* tell role manager to check M/S role */
- bta_sys_conn_open(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
+ bta_sys_conn_open(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), p_scb->app_id, p_scb->peer_addr);
- bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
+ bta_sys_busy(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
if (p_scb->media_type == AVDT_MEDIA_AUDIO) {
/* in normal logic, conns should be bta_av_cb.audio_count - 1,
@@ -2364,7 +2363,7 @@ void bta_av_start_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
UNUSED(p_data);
if (p_scb->started == FALSE && p_scb->co_started == FALSE) {
- bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
+ bta_sys_idle(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
notify_start_failed(p_scb);
}
@@ -2413,7 +2412,8 @@ void bta_av_str_closed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
event = BTA_AV_OPEN_EVT;
p_scb->open_status = BTA_AV_SUCCESS;
- bta_sys_conn_close(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
+ bta_sys_conn_close(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), p_scb->app_id, p_scb->peer_addr);
+
bta_av_cleanup(p_scb, p_data);
(*bta_av_cb.p_cback)(event, &data);
} else {
@@ -2432,7 +2432,8 @@ void bta_av_str_closed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
data.close.disc_rsn = p_scb->disc_rsn;
event = BTA_AV_CLOSE_EVT;
- bta_sys_conn_close(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
+ bta_sys_conn_close(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), p_scb->app_id, p_scb->peer_addr);
+
bta_av_cleanup(p_scb, p_data);
(*bta_av_cb.p_cback)(event, &data);
}
@@ -2506,7 +2507,7 @@ void bta_av_suspend_cfm (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
p_scb->cong = FALSE;
}
- bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
+ bta_sys_idle(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 || bta_av_cb.audio_open_cnt == 1) {
policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
}
diff --git a/components/bt/bluedroid/bta/av/include/bta_av_int.h b/components/bt/bluedroid/bta/av/include/bta_av_int.h
index 3a13c0cc52..0c9da001c6 100644
--- a/components/bt/bluedroid/bta/av/include/bta_av_int.h
+++ b/components/bt/bluedroid/bta/av/include/bta_av_int.h
@@ -153,6 +153,7 @@ enum {
#define BTA_AV_MULTI_AV_SUPPORTED 0x01
#define BTA_AV_MULTI_AV_IN_USE 0x02
+#define TSEP_TO_SYS_ID(x) ((x) == AVDT_TSEP_SRC ? BTA_ID_AV : BTA_ID_AVK)
/*****************************************************************************
** Data types
diff --git a/components/bt/bluedroid/bta/dm/bta_dm_act.c b/components/bt/bluedroid/bta/dm/bta_dm_act.c
index caa4943145..6ffeb9bbd4 100644
--- a/components/bt/bluedroid/bta/dm/bta_dm_act.c
+++ b/components/bt/bluedroid/bta/dm/bta_dm_act.c
@@ -72,9 +72,9 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data);
static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
/* Extended Inquiry Response */
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE && SMP_INCLUDED == TRUE)
+#if (BT_SSP_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data);
-#endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */
+#endif /* (BT_SSP_INCLUDED == TRUE) */
static void bta_dm_set_eir (char *local_name);
#if (SDP_INCLUDED == TRUE)
@@ -218,7 +218,7 @@ const tBTM_APPL_INFO bta_security = {
&bta_dm_new_link_key_cback,
&bta_dm_authentication_complete_cback,
&bta_dm_bond_cancel_complete_cback,
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
&bta_dm_sp_cback,
#else
NULL,
@@ -374,6 +374,12 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH );
/* notify BTA DM is now unactive */
bta_dm_cb.is_bta_dm_active = FALSE;
+#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
+#if (GATTC_INCLUDED == TRUE && GATTC_CACHE_NVS == TRUE)
+ /* clear the gattc cache address list */
+ bta_gattc_co_cache_addr_deinit();
+#endif
+#endif
} else if ( status == BTA_SYS_HW_ON_EVT ) {
/* FIXME: We should not unregister as the SYS shall invoke this callback on a H/W error.
* We need to revisit when this platform has more than one BLuetooth H/W chip */
@@ -403,7 +409,7 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
BTM_SetDeviceClass (dev_class);
#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
-#if (GATTC_INCLUDED == TRUE)
+#if (GATTC_INCLUDED == TRUE && GATTC_CACHE_NVS == TRUE)
// load the gattc cache address list
bta_gattc_co_cache_addr_init();
#endif /* #if (GATTC_INCLUDED = TRUE) */
@@ -596,16 +602,16 @@ void bta_dm_ble_read_adv_tx_power(tBTA_DM_MSG *p_data)
if (p_data->read_tx_power.read_tx_power_cb != NULL) {
BTM_BleReadAdvTxPower(p_data->read_tx_power.read_tx_power_cb);
} else {
- APPL_TRACE_ERROR("%s(), the callback function cann't be NULL.", __func__);
+ APPL_TRACE_ERROR("%s(), the callback function can't be NULL.", __func__);
}
}
void bta_dm_ble_read_rssi(tBTA_DM_MSG *p_data)
{
if (p_data->rssi.read_rssi_cb != NULL) {
- BTM_ReadRSSI(p_data->rssi.remote_addr, p_data->rssi.read_rssi_cb);
+ BTM_ReadRSSI(p_data->rssi.remote_addr, p_data->rssi.transport, p_data->rssi.read_rssi_cb);
} else {
- APPL_TRACE_ERROR("%s(), the callback function cann't be NULL.", __func__);
+ APPL_TRACE_ERROR("%s(), the callback function can't be NULL.", __func__);
}
}
@@ -692,25 +698,29 @@ void bta_dm_set_visibility(tBTA_DM_MSG *p_data)
** Description Removes device, Disconnects ACL link if required.
****
*******************************************************************************/
-void bta_dm_process_remove_device(BD_ADDR bd_addr)
+static void bta_dm_process_remove_device(BD_ADDR bd_addr, tBT_TRANSPORT transport)
{
#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
/* need to remove all pending background connection before unpair */
BTA_GATTC_CancelOpen(0, bd_addr, FALSE);
#endif
- BTM_SecDeleteDevice(bd_addr);
+ BTM_SecDeleteDevice(bd_addr, transport);
#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
/* remove all cached GATT information */
- BTA_GATTC_Refresh(bd_addr);
+ BTA_GATTC_Refresh(bd_addr, false);
#endif
-
if (bta_dm_cb.p_sec_cback) {
tBTA_DM_SEC sec_event;
bdcpy(sec_event.link_down.bd_addr, bd_addr);
sec_event.link_down.status = HCI_SUCCESS;
- bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event);
+ if (transport == BT_TRANSPORT_LE){
+ bta_dm_cb.p_sec_cback(BTA_DM_BLE_DEV_UNPAIRED_EVT, &sec_event);
+ } else {
+ bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event);
+ }
+
}
}
@@ -728,32 +738,22 @@ void bta_dm_remove_device(tBTA_DM_MSG *p_data)
return;
}
- BD_ADDR other_address;
- bdcpy(other_address, p_dev->bd_addr);
-
/* If ACL exists for the device in the remove_bond message*/
BOOLEAN continue_delete_dev = FALSE;
- UINT8 other_transport = BT_TRANSPORT_INVALID;
+ UINT8 transport = p_dev->transport;
- if (BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_LE) ||
- BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_BR_EDR)) {
+ if (BTM_IsAclConnectionUp(p_dev->bd_addr, transport)) {
APPL_TRACE_DEBUG("%s: ACL Up count %d", __func__, bta_dm_cb.device_list.count);
continue_delete_dev = FALSE;
/* Take the link down first, and mark the device for removal when disconnected */
for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
- if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_dev->bd_addr)) {
+ if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_dev->bd_addr)
+ && bta_dm_cb.device_list.peer_device[i].transport == transport) {
bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
btm_remove_acl( p_dev->bd_addr, bta_dm_cb.device_list.peer_device[i].transport);
APPL_TRACE_DEBUG("%s:transport = %d", __func__,
bta_dm_cb.device_list.peer_device[i].transport);
-
- /* save the other transport to check if device is connected on other_transport */
- if (bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_LE) {
- other_transport = BT_TRANSPORT_BR_EDR;
- } else {
- other_transport = BT_TRANSPORT_LE;
- }
break;
}
}
@@ -761,35 +761,9 @@ void bta_dm_remove_device(tBTA_DM_MSG *p_data)
continue_delete_dev = TRUE;
}
- // If it is DUMO device and device is paired as different address, unpair that device
- // if different address
- BOOLEAN continue_delete_other_dev = FALSE;
- if ((other_transport && (BTM_ReadConnectedTransportAddress(other_address, other_transport))) ||
- (!other_transport && (BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_BR_EDR) ||
- BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_LE)))) {
- continue_delete_other_dev = FALSE;
- /* Take the link down first, and mark the device for removal when disconnected */
- for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
- if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, other_address)) {
- bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
- btm_remove_acl(other_address, bta_dm_cb.device_list.peer_device[i].transport);
- break;
- }
- }
- } else {
- APPL_TRACE_DEBUG("%s: continue to delete the other dev ", __func__);
- continue_delete_other_dev = TRUE;
- }
-
/* Delete the device mentioned in the msg */
if (continue_delete_dev) {
- bta_dm_process_remove_device(p_dev->bd_addr);
- }
-
- /* Delete the other paired device too */
- BD_ADDR dummy_bda = {0};
- if (continue_delete_other_dev && (bdcmp(other_address, dummy_bda) != 0)) {
- bta_dm_process_remove_device(other_address);
+ bta_dm_process_remove_device(p_dev->bd_addr, transport);
}
}
@@ -880,14 +854,14 @@ void bta_dm_close_acl(tBTA_DM_MSG *p_data)
}
/* if to remove the device from security database ? do it now */
else if (p_remove_acl->remove_dev) {
- if (!BTM_SecDeleteDevice(p_remove_acl->bd_addr)) {
+ if (!BTM_SecDeleteDevice(p_remove_acl->bd_addr, p_remove_acl->transport)) {
APPL_TRACE_ERROR("delete device from security database failed.");
}
#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
/* need to remove all pending background connection if any */
BTA_GATTC_CancelOpen(0, p_remove_acl->bd_addr, FALSE);
/* remove all cached GATT information */
- BTA_GATTC_Refresh(p_remove_acl->bd_addr);
+ BTA_GATTC_Refresh(p_remove_acl->bd_addr, false);
#endif
}
/* otherwise, no action needed */
@@ -1121,6 +1095,28 @@ void bta_dm_confirm(tBTA_DM_MSG *p_data)
}
#endif ///SMP_INCLUDED == TRUE
+/*******************************************************************************
+**
+** Function bta_dm_key_req
+**
+** Description Send the user passkey request reply in response to a
+** request from BTM
+**
+** Returns void
+**
+*******************************************************************************/
+#if (SMP_INCLUDED == TRUE && BT_SSP_INCLUDED)
+void bta_dm_key_req(tBTA_DM_MSG *p_data)
+{
+ tBTM_STATUS res = BTM_NOT_AUTHORIZED;
+
+ if (p_data->key_req.accept == TRUE) {
+ res = BTM_SUCCESS;
+ }
+ BTM_PasskeyReqReply(res, p_data->key_req.bd_addr, p_data->key_req.passkey);
+}
+#endif ///SMP_INCLUDED == TRUE && BT_SSP_INCLUDED
+
/*******************************************************************************
**
** Function bta_dm_loc_oob
@@ -2841,7 +2837,7 @@ static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev
return BTM_SUCCESS;
}
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
/*******************************************************************************
**
** Function bta_dm_sp_cback
@@ -2865,7 +2861,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
/* TODO_SP */
switch (event) {
case BTM_SP_IO_REQ_EVT:
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
/* translate auth_req */
bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap,
&p_data->io_req.oob_data, &p_data->io_req.auth_req, p_data->io_req.is_orig);
@@ -2877,7 +2873,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
break;
case BTM_SP_IO_RSP_EVT:
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap,
p_data->io_rsp.oob_data, p_data->io_rsp.auth_req );
#endif
@@ -2892,10 +2888,10 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps;
/* continue to next case */
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
/* Passkey entry mode, mobile device with output capability is very
unlikely to receive key request, so skip this event */
- /*case BTM_SP_KEY_REQ_EVT: */
+ case BTM_SP_KEY_REQ_EVT:
case BTM_SP_KEY_NOTIF_EVT:
#endif
if (BTM_SP_CFM_REQ_EVT == event) {
@@ -2943,6 +2939,27 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
}
}
+ if (BTM_SP_KEY_REQ_EVT == event) {
+ pin_evt = BTA_DM_SP_KEY_REQ_EVT;
+ /* If the device name is not known, save bdaddr and devclass
+ and initiate a name request with values from key_notif */
+ if (p_data->key_notif.bd_name[0] == 0) {
+ bta_dm_cb.pin_evt = pin_evt;
+ bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
+ BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
+ if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback,
+ BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
+ return BTM_CMD_STARTED;
+ }
+ APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
+ } else {
+ bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
+ BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
+ BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
+ (char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
+ sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
+ }
+ }
bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
break;
@@ -2996,7 +3013,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
APPL_TRACE_EVENT("dm status: %d", status);
return status;
}
-#endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */
+#endif /* (BT_SSP_INCLUDED == TRUE) */
#endif ///SMP_INCLUDED == TRUE
@@ -3283,7 +3300,7 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
}
if ( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING ) {
- if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr)) {
+ if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bta_dm_cb.device_list.peer_device[i].transport)) {
issue_unpair_cb = TRUE;
}
@@ -3331,12 +3348,12 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
}
}
if (conn.link_down.is_removed) {
- BTM_SecDeleteDevice(p_bda);
+ BTM_SecDeleteDevice(p_bda, p_data->acl_change.transport);
#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
/* need to remove all pending background connection */
BTA_GATTC_CancelOpen(0, p_bda, FALSE);
/* remove all cached GATT information */
- BTA_GATTC_Refresh(p_bda);
+ BTA_GATTC_Refresh(p_bda, false);
#endif
}
@@ -3345,7 +3362,11 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
if ( bta_dm_cb.p_sec_cback ) {
bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn);
if ( issue_unpair_cb ) {
- bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn);
+ if (p_data->acl_change.transport == BT_TRANSPORT_LE) {
+ bta_dm_cb.p_sec_cback(BTA_DM_BLE_DEV_UNPAIRED_EVT, &conn);
+ } else {
+ bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn);
+ }
}
}
}
@@ -3505,12 +3526,12 @@ static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
APPL_TRACE_ERROR(" %s Device does not exist in DB", __FUNCTION__);
}
} else {
- BTM_SecDeleteDevice (remote_bd_addr);
+ BTM_SecDeleteDevice (remote_bd_addr, bta_dm_cb.device_list.peer_device[index].transport);
#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
/* need to remove all pending background connection */
BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
/* remove all cached GATT information */
- BTA_GATTC_Refresh(remote_bd_addr);
+ BTA_GATTC_Refresh(remote_bd_addr, false);
#endif
}
}
@@ -4257,7 +4278,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
switch (event) {
case BTM_LE_IO_REQ_EVT:
- // #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+ // #if (BT_SSP_INCLUDED == TRUE)
bta_dm_co_ble_io_req(bda,
&p_data->io_req.io_cap,
@@ -4659,7 +4680,7 @@ void bta_dm_ble_set_rand_address(tBTA_DM_MSG *p_data)
void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data)
{
if (p_data->hdr.event != BTA_DM_API_BLE_STOP_ADV_EVT) {
- APPL_TRACE_ERROR("Invalid BTA event,cann't stop the BLE adverting\n");
+ APPL_TRACE_ERROR("Invalid BTA event,can't stop the BLE adverting\n");
}
btm_ble_stop_adv();
diff --git a/components/bt/bluedroid/bta/dm/bta_dm_api.c b/components/bt/bluedroid/bta/dm/bta_dm_api.c
index 1f2262ae90..10610fd6f0 100644
--- a/components/bt/bluedroid/bta/dm/bta_dm_api.c
+++ b/components/bt/bluedroid/bta/dm/bta_dm_api.c
@@ -206,12 +206,13 @@ void BTA_DmBleReadAdvTxPower(tBTA_CMPL_CB *cmpl_cb)
}
}
-void BTA_DmBleReadRSSI(BD_ADDR remote_addr, tBTA_CMPL_CB *cmpl_cb)
+void BTA_DmBleReadRSSI(BD_ADDR remote_addr, tBTA_TRANSPORT transport, tBTA_CMPL_CB *cmpl_cb)
{
tBTA_DM_API_READ_RSSI *p_msg;
if ((p_msg = (tBTA_DM_API_READ_RSSI *)osi_malloc(sizeof(tBTA_DM_API_READ_RSSI))) != NULL) {
p_msg->hdr.event = BTA_DM_API_BLE_READ_RSSI_EVT;
memcpy(p_msg->remote_addr, remote_addr, sizeof(BD_ADDR));
+ p_msg->transport = transport;
p_msg->read_rssi_cb = cmpl_cb;
bta_sys_sendmsg(p_msg);
}
@@ -510,6 +511,29 @@ void BTA_DmConfirm(BD_ADDR bd_addr, BOOLEAN accept)
}
}
+/*******************************************************************************
+**
+** Function BTA_DmPasskeyReqReply
+**
+** Description This function is called to provide the passkey for
+** Simple Pairing in response to BTA_DM_SP_KEY_REQ_EVT
+**
+** Returns void
+**
+*******************************************************************************/
+#if (BT_SSP_INCLUDED == TRUE)
+void BTA_DmPasskeyReqReply(BOOLEAN accept, BD_ADDR bd_addr, UINT32 passkey)
+{
+ tBTA_DM_API_KEY_REQ *p_msg;
+ if ((p_msg = (tBTA_DM_API_KEY_REQ *) osi_malloc(sizeof(tBTA_DM_API_KEY_REQ))) != NULL) {
+ p_msg->hdr.event = BTA_DM_API_KEY_REQ_EVT;
+ bdcpy(p_msg->bd_addr, bd_addr);
+ p_msg->accept = accept;
+ p_msg->passkey = passkey;
+ bta_sys_sendmsg(p_msg);
+ }
+}
+#endif ///BT_SSP_INCLUDED == TRUE
/*******************************************************************************
**
** Function BTA_DmAddDevice
@@ -569,7 +593,7 @@ void BTA_DmAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class, LINK_KEY link_key,
** Returns void
**
*******************************************************************************/
-tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr)
+tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr, tBT_TRANSPORT transport)
{
tBTA_DM_API_REMOVE_DEVICE *p_msg;
@@ -578,6 +602,7 @@ tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr)
p_msg->hdr.event = BTA_DM_API_REMOVE_DEVICE_EVT;
bdcpy(p_msg->bd_addr, bd_addr);
+ p_msg->transport = transport;
bta_sys_sendmsg(p_msg);
} else {
return BTA_FAILURE;
diff --git a/components/bt/bluedroid/bta/dm/bta_dm_co.c b/components/bt/bluedroid/bta/dm/bta_dm_co.c
index dbfabc3b7a..01641ba9c7 100644
--- a/components/bt/bluedroid/bta/dm/bta_dm_co.c
+++ b/components/bt/bluedroid/bta/dm/bta_dm_co.c
@@ -44,6 +44,16 @@ tBTE_APPL_CFG bte_appl_cfg = {
};
#endif
+#if (defined CLASSIC_BT_INCLUDED && CLASSIC_BT_INCLUDED == TRUE && BT_SSP_INCLUDED == TRUE)
+#include "common/bte_appl.h"
+#include "btm_int.h"
+tBTE_BT_APPL_CFG bte_bt_appl_cfg = {
+ 0, //Todo, Authentication requirements
+ BTM_LOCAL_IO_CAPS,
+ NULL, //Todo, OOB data
+};
+#endif
+
/*******************************************************************************
**
** Function bta_dm_co_get_compress_memory
@@ -65,6 +75,34 @@ BOOLEAN bta_dm_co_get_compress_memory(tBTA_SYS_ID id, UINT8 **memory_p, UINT32 *
return TRUE;
}
+/*******************************************************************************
+**
+** Function bta_dm_co_bt_set_io_cap
+**
+** Description This function is used to set IO capabilities
+**
+** Parameters bt_io_cap - IO capabilities
+**
+** @return - ESP_BT_STATUS_SUCCESS : success
+** - other : failed
+**
+*******************************************************************************/
+esp_err_t bta_dm_co_bt_set_io_cap(UINT8 bt_io_cap)
+{
+ esp_err_t ret = ESP_BT_STATUS_SUCCESS;
+#if (BT_SSP_INCLUDED == TRUE)
+ if(bt_io_cap < BTM_IO_CAP_MAX ) {
+ bte_bt_appl_cfg.bt_io_cap = bt_io_cap;
+ btm_cb.devcb.loc_io_caps = bt_io_cap;
+ ret = ESP_BT_STATUS_SUCCESS;
+ } else {
+ ret = ESP_BT_STATUS_FAIL;
+ APPL_TRACE_ERROR("%s error:Invalid io cap value.",__func__);
+ }
+#endif ///BT_SSP_INCLUDED == TRUE
+ return ret;
+}
+
/*******************************************************************************
**
** Function bta_dm_co_io_req
diff --git a/components/bt/bluedroid/bta/dm/bta_dm_main.c b/components/bt/bluedroid/bta/dm/bta_dm_main.c
index 25977e7a49..40c41617ad 100644
--- a/components/bt/bluedroid/bta/dm/bta_dm_main.c
+++ b/components/bt/bluedroid/bta/dm/bta_dm_main.c
@@ -74,12 +74,15 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
/* simple pairing events */
#if (SMP_INCLUDED == TRUE)
bta_dm_confirm, /* 18 BTA_DM_API_CONFIRM_EVT */
+#if (BT_SSP_INCLUDED == TRUE)
+ bta_dm_key_req, /* 19 BTA_DM_API_KEY_REQ_EVT */
+#endif ///BT_SSP_INCLUDED == TRUE
bta_dm_set_encryption, /* BTA_DM_API_SET_ENCRYPTION_EVT */
#endif ///SMP_INCLUDED == TRUE
#if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
- bta_dm_loc_oob, /* 20 BTA_DM_API_LOC_OOB_EVT */
- bta_dm_ci_io_req_act, /* 21 BTA_DM_CI_IO_REQ_EVT */
- bta_dm_ci_rmt_oob_act, /* 22 BTA_DM_CI_RMT_OOB_EVT */
+ bta_dm_loc_oob, /* 21 BTA_DM_API_LOC_OOB_EVT */
+ bta_dm_ci_io_req_act, /* 22 BTA_DM_CI_IO_REQ_EVT */
+ bta_dm_ci_rmt_oob_act, /* 23 BTA_DM_CI_RMT_OOB_EVT */
#endif /* BTM_OOB_INCLUDED */
@@ -119,7 +122,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
data to HCI */
bta_dm_ble_set_adv_config_raw, /* BTA_DM_API_BLE_SET_ADV_CONFIG_RAW_EVT */
bta_dm_ble_set_scan_rsp, /* BTA_DM_API_BLE_SET_SCAN_RSP_EVT */
- /* New function to allow set raw scan
+ /* New function to allow set raw scan
response data to HCI */
bta_dm_ble_set_scan_rsp_raw, /* BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT */
bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */
diff --git a/components/bt/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/bluedroid/bta/dm/include/bta_dm_int.h
index 8ee1dda61b..588886d302 100644
--- a/components/bt/bluedroid/bta/dm/include/bta_dm_int.h
+++ b/components/bt/bluedroid/bta/dm/include/bta_dm_int.h
@@ -71,7 +71,9 @@ enum {
#if (SMP_INCLUDED == TRUE)
/* simple pairing events */
BTA_DM_API_CONFIRM_EVT,
-
+#if (BT_SSP_INCLUDED == TRUE)
+ BTA_DM_API_KEY_REQ_EVT,
+#endif ///BT_SSP_INCLUDED == TRUE
BTA_DM_API_SET_ENCRYPTION_EVT,
#endif ///SMP_INCLUDED == TRUE
#if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
@@ -196,6 +198,7 @@ typedef struct {
typedef struct {
BT_HDR hdr;
BD_ADDR remote_addr;
+ tBTA_TRANSPORT transport;
tBTA_CMPL_CB *read_rssi_cb;
}tBTA_DM_API_READ_RSSI;
@@ -291,6 +294,14 @@ typedef struct {
BOOLEAN accept;
} tBTA_DM_API_CONFIRM;
+/* data type for BTA_DM_API_KEY_REQ_EVT */
+typedef struct {
+ BT_HDR hdr;
+ BD_ADDR bd_addr;
+ BOOLEAN accept;
+ UINT32 passkey;
+} tBTA_DM_API_KEY_REQ;
+
/* data type for BTA_DM_CI_IO_REQ_EVT */
typedef struct {
BT_HDR hdr;
@@ -391,6 +402,7 @@ typedef struct {
typedef struct {
BT_HDR hdr;
BD_ADDR bd_addr;
+ UINT8 transport;
} tBTA_DM_API_REMOVE_DEVICE;
/* data type for BTA_DM_API_EXECUTE_CBACK_EVT */
@@ -746,6 +758,7 @@ typedef union {
tBTA_DM_API_LOC_OOB loc_oob;
tBTA_DM_API_CONFIRM confirm;
+ tBTA_DM_API_KEY_REQ key_req;
tBTA_DM_CI_IO_REQ ci_io_req;
tBTA_DM_CI_RMT_OOB ci_rmt_oob;
@@ -1223,6 +1236,7 @@ extern void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data);
#endif
extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data);
extern void bta_dm_confirm(tBTA_DM_MSG *p_data);
+extern void bta_dm_key_req(tBTA_DM_MSG *p_data);
#if (BTM_OOB_INCLUDED == TRUE)
extern void bta_dm_loc_oob(tBTA_DM_MSG *p_data);
extern void bta_dm_ci_io_req_act(tBTA_DM_MSG *p_data);
diff --git a/components/bt/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/bluedroid/bta/gatt/bta_gattc_act.c
index e836003dd4..29a9d47279 100644
--- a/components/bt/bluedroid/bta/gatt/bta_gattc_act.c
+++ b/components/bt/bluedroid/bta/gatt/bta_gattc_act.c
@@ -65,6 +65,7 @@ static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb);
static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested);
+static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data);
static tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda);
static tGATT_CBACK bta_gattc_cl_cback = {
@@ -72,7 +73,7 @@ static tGATT_CBACK bta_gattc_cl_cback = {
bta_gattc_cmpl_cback,
bta_gattc_disc_res_cback,
bta_gattc_disc_cmpl_cback,
- NULL,
+ bta_gattc_req_cback,
bta_gattc_enc_cmpl_cback,
bta_gattc_cong_cback
};
@@ -666,11 +667,16 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
if (p_clcb->p_srcb->p_srvc_cache == NULL ||
p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) {
if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
+#if (GATTC_CACHE_NVS == TRUE)
p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
if (bta_gattc_cache_load(p_clcb)) {
p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
- } else { /* cache is building */
+ //register service change
+ bta_gattc_register_service_change_notify(p_clcb->bta_conn_id, p_clcb->bda);
+ } else
+#endif
+ { /* cache is building */
p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
/* cache load failure, start discovery */
bta_gattc_start_discover(p_clcb, NULL);
@@ -1016,9 +1022,10 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
list_free(p_clcb->p_srcb->p_srvc_cache);
p_clcb->p_srcb->p_srvc_cache = NULL;
}
-
+#if(GATTC_CACHE_NVS == TRUE)
/* used to reset cache in application */
bta_gattc_cache_reset(p_clcb->p_srcb->server_bda);
+#endif
}
if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) {
/* release pending attribute list buffer */
@@ -1291,6 +1298,7 @@ void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
cb_data.write.conn_id = p_clcb->bta_conn_id;
if (p_conn && p_conn->svc_change_descr_handle == cb_data.write.handle) {
if(cb_data.write.status != BTA_GATT_OK) {
+ p_conn->write_remote_svc_change_ccc_done = FALSE;
APPL_TRACE_ERROR("service change write ccc failed");
}
return;
@@ -1716,7 +1724,6 @@ void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
}
if (found) {
bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
- bta_gattc_cache_reset(p_msg->api_conn.remote_bda);
return;
}
}
@@ -1726,8 +1733,6 @@ void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
p_srvc_cb->p_srvc_cache = NULL;
}
}
- /* used to reset cache in application */
- bta_gattc_cache_reset(p_msg->api_conn.remote_bda);
}
void bta_gattc_process_api_cache_assoc(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
@@ -1873,6 +1878,10 @@ BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
/* if connection available, refresh cache by doing discovery now */
if (p_clcb != NULL) {
+ tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find(p_clcb->bda);
+ if(p_conn) {
+ p_conn->write_remote_svc_change_ccc_done = FALSE;
+ }
bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
}
}
@@ -2085,6 +2094,27 @@ static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested)
}
}
+/*******************************************************************************
+**
+** Function bta_gattc_req_cback
+**
+** Description GATT request command callback for BTA GATT client.
+**
+** Returns void
+**
+********************************************************************************/
+static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data)
+{
+ /* GATTC doesn't need to process the GATT request commands.
+ * Add this callback here to avoid the warning "Call back not found for application"
+ * printed in the function gatt_sr_send_req_callback
+ * */
+ UNUSED (conn_id);
+ UNUSED (trans_id) ;
+ UNUSED (type);
+ UNUSED (p_data);
+}
+
#if BLE_INCLUDED == TRUE
/*******************************************************************************
**
@@ -2257,6 +2287,10 @@ tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_
tBT_UUID gatt_service_uuid = {LEN_UUID_16, {UUID_SERVCLASS_GATT_SERVER}};
tBT_UUID gatt_service_change_uuid = {LEN_UUID_16, {GATT_UUID_GATT_SRV_CHGD}};
tBT_UUID gatt_ccc_uuid = {LEN_UUID_16, {GATT_UUID_CHAR_CLIENT_CONFIG}};
+ tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find_alloc(remote_bda);
+ if(p_conn && p_conn->write_remote_svc_change_ccc_done) {
+ return SERVICE_CHANGE_CCC_WRITTEN_SUCCESS;
+ }
p_srcb = bta_gattc_find_srcb(remote_bda);
if ((p_srcb != NULL) && (p_srcb->p_srvc_cache != NULL)) {
@@ -2321,9 +2355,9 @@ tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_
}
if (gatt_ccc_found == TRUE){
- tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find_alloc(remote_bda);
if (p_conn) {
p_conn->svc_change_descr_handle = p_desc->handle;
+ p_conn->write_remote_svc_change_ccc_done = TRUE;
}
result = SERVICE_CHANGE_CCC_WRITTEN_SUCCESS;
uint16_t indicate_value = GATT_CLT_CONFIG_INDICATION;
diff --git a/components/bt/bluedroid/bta/gatt/bta_gattc_api.c b/components/bt/bluedroid/bta/gatt/bta_gattc_api.c
index b7c292a51e..45a155e1e6 100644
--- a/components/bt/bluedroid/bta/gatt/bta_gattc_api.c
+++ b/components/bt/bluedroid/bta/gatt/bta_gattc_api.c
@@ -912,12 +912,20 @@ tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications (tBTA_GATTC_IF client_if,
** Description Refresh the server cache of the remote device
**
** Parameters remote_bda: remote device BD address.
+** erase_flash: delete cache from nvs flash
**
** Returns void
**
*******************************************************************************/
-void BTA_GATTC_Refresh(BD_ADDR remote_bda)
+void BTA_GATTC_Refresh(BD_ADDR remote_bda, bool erase_flash)
{
+#if(GATTC_CACHE_NVS == TRUE)
+ if(erase_flash) {
+ /* used to reset cache in application */
+ bta_gattc_cache_reset(remote_bda);
+ }
+#endif
+
tBTA_GATTC_API_OPEN *p_buf;
if ((p_buf = (tBTA_GATTC_API_OPEN *) osi_malloc(sizeof(tBTA_GATTC_API_OPEN))) != NULL) {
diff --git a/components/bt/bluedroid/bta/gatt/bta_gattc_cache.c b/components/bt/bluedroid/bta/gatt/bta_gattc_cache.c
index 8a5625356c..90a9d13502 100644
--- a/components/bt/bluedroid/bta/gatt/bta_gattc_cache.c
+++ b/components/bt/bluedroid/bta/gatt/bta_gattc_cache.c
@@ -346,6 +346,7 @@ static tBTA_GATT_STATUS bta_gattc_add_attr_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
tBT_UUID *p_uuid,
UINT8 property,
UINT16 incl_srvc_s_handle,
+ UINT16 incl_srvc_e_handle,
tBTA_GATTC_ATTR_TYPE type)
{
#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
@@ -370,18 +371,13 @@ static tBTA_GATT_STATUS bta_gattc_add_attr_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
isvc->handle = handle;
memcpy(&isvc->uuid, p_uuid, sizeof(tBT_UUID));
isvc->incl_srvc_s_handle = incl_srvc_s_handle;
+ isvc->incl_srvc_e_handle = incl_srvc_e_handle;
isvc->owning_service = service;
isvc->included_service = bta_gattc_find_matching_service(
p_srvc_cb->p_srvc_cache, incl_srvc_s_handle);
if (!isvc->included_service) {
- // if it is a secondary service, wait to update later
- if(property == 0){
- p_srvc_cb->update_sec_sev = true;
- } else {
- APPL_TRACE_ERROR("%s: Illegal action to add non-existing included service!", __func__);
- osi_free(isvc);
- return GATT_WRONG_STATE;
- }
+ // if can't find included service, wait to update later
+ p_srvc_cb->update_incl_srvc = true;
}
list_append(service->included_svc, isvc);
@@ -604,10 +600,10 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
return;
}
}
- //update include service when have secondary service
- if(p_srvc_cb->update_sec_sev) {
+ // if update_incl_srvc is true, update include service
+ if(p_srvc_cb->update_incl_srvc) {
bta_gattc_update_include_service(p_srvc_cb->p_srvc_cache);
- p_srvc_cb->update_sec_sev = false;
+ p_srvc_cb->update_incl_srvc = false;
}
/* no service found at all, the end of server discovery*/
APPL_TRACE_DEBUG("%s no more services found", __func__);
@@ -622,10 +618,11 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
}
#endif
+#if(GATTC_CACHE_NVS == TRUE)
/* save cache to NV */
p_clcb->p_srcb->state = BTA_GATTC_SERV_SAVE;
-
bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id);
+#endif
bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
}
/*******************************************************************************
@@ -995,6 +992,7 @@ void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_
&p_data->value.incl_service.service_type,
pri_srvc,
p_data->value.incl_service.s_handle,
+ p_data->value.incl_service.e_handle,
BTA_GATTC_ATTR_TYPE_INCL_SRVC);
break;
@@ -1008,10 +1006,14 @@ void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_
break;
case GATT_DISC_CHAR_DSCPT:
- bta_gattc_add_attr_to_cache(p_srvc_cb, p_data->handle, &p_data->type, 0,
- 0 /* incl_srvc_handle */,
+ bta_gattc_add_attr_to_cache(p_srvc_cb,
+ p_data->handle,
+ &p_data->type,
+ 0,
+ 0 /* incl_srvc_s_handle */,
+ 0 /* incl_srvc_e_handle */,
BTA_GATTC_ATTR_TYPE_CHAR_DESCR);
- break;
+ break;
}
}
}
@@ -1352,7 +1354,7 @@ void bta_gattc_get_db_with_opration(UINT16 conn_id,
BTGATT_DB_INCLUDED_SERVICE,
p_isvc->handle,
p_isvc->incl_srvc_s_handle /* s_handle */,
- 0 /* e_handle */,
+ p_isvc->incl_srvc_e_handle /* e_handle */,
p_isvc->handle,
p_isvc->uuid,
0 /* property */);
@@ -1650,7 +1652,8 @@ void bta_gattc_get_db_size_handle(UINT16 conn_id, UINT16 start_handle, UINT16 en
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
if (p_clcb == NULL) {
- return NULL;
+ *count = 0;
+ return;
}
tBTA_GATTC_SERV *p_srcb = p_clcb->p_srcb;
@@ -1919,12 +1922,21 @@ void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srvc_cb, UINT16 num_attr,
break;
case BTA_GATTC_ATTR_TYPE_CHAR_DESCR:
+ bta_gattc_add_attr_to_cache(p_srvc_cb,
+ p_attr->s_handle,
+ &p_attr->uuid,
+ p_attr->prop,
+ p_attr->incl_srvc_s_handle,
+ p_attr->incl_srvc_e_handle,
+ p_attr->attr_type);
+ break;
case BTA_GATTC_ATTR_TYPE_INCL_SRVC:
bta_gattc_add_attr_to_cache(p_srvc_cb,
p_attr->s_handle,
&p_attr->uuid,
p_attr->prop,
- p_attr->incl_srvc_handle,
+ p_attr->incl_srvc_s_handle,
+ p_attr->incl_srvc_e_handle,
p_attr->attr_type);
break;
}
@@ -1943,8 +1955,8 @@ void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srvc_cb, UINT16 num_attr,
**
*******************************************************************************/
void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_handle,
- UINT16 e_handle, tBT_UUID uuid, UINT8 prop, UINT16 incl_srvc_handle,
- BOOLEAN is_primary)
+ UINT16 e_handle, tBT_UUID uuid, UINT8 prop, UINT16 incl_srvc_s_handle,
+ UINT16 incl_srvc_e_handle, BOOLEAN is_primary)
{
p_attr->s_handle = s_handle;
p_attr->e_handle = e_handle;
@@ -1952,7 +1964,8 @@ void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_han
p_attr->is_primary = is_primary;
p_attr->id = 0;
p_attr->prop = prop;
- p_attr->incl_srvc_handle = incl_srvc_handle;
+ p_attr->incl_srvc_s_handle = incl_srvc_s_handle;
+ p_attr->incl_srvc_e_handle = incl_srvc_e_handle;
memcpy(&p_attr->uuid, &uuid, sizeof(tBT_UUID));
}
@@ -1992,7 +2005,8 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
p_cur_srvc->e_handle,
p_cur_srvc->uuid,
0 /* properties */,
- 0 /* incl_srvc_handle */,
+ 0 /* incl_srvc_s_handle */,
+ 0 /* incl_srvc_e_handle */,
p_cur_srvc->is_primary);
}
@@ -2013,7 +2027,8 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
0,
p_char->uuid,
p_char->properties,
- 0 /* incl_srvc_handle */,
+ 0 /* incl_srvc_s_handle */,
+ 0 /* incl_srvc_e_handle */,
FALSE);
if (!p_char->descriptors || list_is_empty(p_char->descriptors))
@@ -2029,7 +2044,8 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
0,
p_desc->uuid,
0 /* properties */,
- 0 /* incl_srvc_handle */,
+ 0 /* incl_srvc_s_handle */,
+ 0 /* incl_srvc_e_handle */,
FALSE);
}
}
@@ -2048,6 +2064,7 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
p_isvc->uuid,
0 /* properties */,
p_isvc->included_service->s_handle,
+ p_isvc->included_service->e_handle,
FALSE);
}
}
diff --git a/components/bt/bluedroid/bta/gatt/bta_gattc_co.c b/components/bt/bluedroid/bta/gatt/bta_gattc_co.c
index 6c6fc460d3..1a1599af55 100644
--- a/components/bt/bluedroid/bta/gatt/bta_gattc_co.c
+++ b/components/bt/bluedroid/bta/gatt/bta_gattc_co.c
@@ -75,7 +75,7 @@ static void cacheReset(BD_ADDR bda)
#else
-static const char *cache_key = "gattc_cahe_key";
+static const char *cache_key = "gattc_cache_key";
static const char *cache_addr = "cache_addr_tab";
nvs_handle nvs_fp;
@@ -144,7 +144,7 @@ static void cacheReset(BD_ADDR bda)
char fname[255] = {0};
getFilename(fname, bda);
UINT8 index = 0;
- //cache_env.cache_addr
+ //cache_env.cache_addr
if ((index = bta_gattc_co_find_addr_in_cache(bda)) != INVALID_ADDR_NUM) {
//clear the association address pending in the source address.
bta_gattc_co_cache_clear_assoc_addr(bda);
@@ -152,7 +152,22 @@ static void cacheReset(BD_ADDR bda)
nvs_erase_all(cache_env.cache_addr[index].cache_fp);
nvs_close(cache_env.cache_addr[index].cache_fp);
cache_env.cache_addr[index].is_open = FALSE;
+ } else {
+ cacheOpen(bda, false, &index);
+ if (cache_env.cache_addr[index].is_open) {
+ nvs_erase_all(cache_env.cache_addr[index].cache_fp);
+ nvs_close(cache_env.cache_addr[index].cache_fp);
+ cache_env.cache_addr[index].is_open = FALSE;
+ } else {
+ APPL_TRACE_ERROR("%s cacheOpen failed", __func__);
+ return;
+ }
}
+ if(cache_env.num_addr == 0) {
+ APPL_TRACE_ERROR("%s cache addr list error", __func__);
+ return;
+ }
+
UINT8 num = cache_env.num_addr;
//delete the server_bda in the addr_info list.
for(UINT8 i = index; i < (num - 1); i++) {
@@ -160,6 +175,40 @@ static void cacheReset(BD_ADDR bda)
}
//reduced the number address counter also
cache_env.num_addr--;
+
+ //update addr list to nvs flash
+ if(cache_env.num_addr > 0) {
+ //update
+ UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF);
+ if(!p_buf) {
+ APPL_TRACE_ERROR("%s malloc error", __func__);
+ return;
+ }
+ UINT16 length = cache_env.num_addr*(sizeof(BD_ADDR) + sizeof(hash_key_t));
+ for (UINT8 i = 0; i < cache_env.num_addr; i++) {
+ //copy the address to the buffer.
+ memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)), cache_env.cache_addr[i].addr, sizeof(BD_ADDR));
+ //copy the hash key to the buffer.
+ memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)) + sizeof(BD_ADDR),
+ cache_env.cache_addr[i].hash_key, sizeof(hash_key_t));
+ }
+ if (cache_env.is_open) {
+ if (nvs_set_blob(cache_env.addr_fp, cache_key, p_buf, length) != ESP_OK) {
+ APPL_TRACE_WARNING("%s, nvs set blob failed", __func__);
+ }
+ }
+ osi_free(p_buf);
+
+ } else {
+ //erase
+ if (cache_env.is_open) {
+ nvs_erase_all(cache_env.addr_fp);
+ nvs_close(cache_env.addr_fp);
+ cache_env.is_open = FALSE;
+ } else {
+ APPL_TRACE_WARNING("cache_env status is error");
+ }
+ }
}
}
@@ -325,10 +374,11 @@ void bta_gattc_co_cache_addr_init(void)
esp_err_t err_code;
UINT8 num_addr;
UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF);
- size_t length = 0;
+ size_t length = MAX_ADDR_LIST_CACHE_BUF;
if ((err_code = nvs_open(cache_addr, NVS_READWRITE, &fp)) == ESP_OK) {
cache_env.addr_fp = fp;
+ cache_env.is_open = TRUE;
// Read previously saved blob if available
if ((err_code = nvs_get_blob(fp, cache_key, p_buf, &length)) != ESP_OK) {
if(err_code != ESP_ERR_NVS_NOT_FOUND) {
@@ -361,6 +411,26 @@ void bta_gattc_co_cache_addr_init(void)
return;
}
+void bta_gattc_co_cache_addr_deinit(void)
+{
+ if(!cache_env.is_open) {
+ return;
+ }
+ nvs_close(cache_env.addr_fp);
+ cache_env.is_open = false;
+
+ for(UINT8 i = 0; i< cache_env.num_addr; i++) {
+ cache_addr_info_t *addr_info = &cache_env.cache_addr[i];
+ if(addr_info) {
+ nvs_close(addr_info->cache_fp);
+ addr_info->is_open = false;
+ if(addr_info->assoc_addr) {
+ list_free(addr_info->assoc_addr);
+ }
+ }
+ }
+}
+
BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda)
{
UINT8 addr_index = 0;
diff --git a/components/bt/bluedroid/bta/gatt/bta_gatts_co.c b/components/bt/bluedroid/bta/gatt/bta_gatts_co.c
index 1bc7881cc9..2130005a11 100644
--- a/components/bt/bluedroid/bta/gatt/bta_gatts_co.c
+++ b/components/bt/bluedroid/bta/gatt/bta_gatts_co.c
@@ -125,7 +125,7 @@ void bta_gatts_co_update_handle_range(BOOLEAN is_add, tBTA_GATTS_HNDL_RANGE *p_h
**
** Returns TRUE - if the request is processed successfully and
** the response is returned in p_rsp.
-** FASLE - if the request can not be processed
+** FALSE - if the request can not be processed
**
*******************************************************************************/
BOOLEAN bta_gatts_co_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd,
diff --git a/components/bt/bluedroid/bta/gatt/include/bta_gattc_int.h b/components/bt/bluedroid/bta/gatt/include/bta_gattc_int.h
index 89864aacea..68887f0891 100644
--- a/components/bt/bluedroid/bta/gatt/include/bta_gattc_int.h
+++ b/components/bt/bluedroid/bta/gatt/include/bta_gattc_int.h
@@ -300,7 +300,7 @@ typedef struct {
UINT16 attr_index; /* cahce NV saving/loading attribute index */
UINT16 mtu;
- bool update_sec_sev;
+ bool update_incl_srvc;
} tBTA_GATTC_SERV;
#ifndef BTA_GATTC_NOTIF_REG_MAX
@@ -365,7 +365,8 @@ typedef struct {
typedef struct {
BOOLEAN in_use;
BD_ADDR remote_bda;
- UINT16 svc_change_descr_handle;
+ UINT16 svc_change_descr_handle;
+ BOOLEAN write_remote_svc_change_ccc_done;
} tBTA_GATTC_CONN;
enum {
diff --git a/components/bt/bluedroid/bta/hf_client/bta_hf_client_sco.c b/components/bt/bluedroid/bta/hf_client/bta_hf_client_sco.c
index 744edc9179..20b0cc7855 100644
--- a/components/bt/bluedroid/bta/hf_client/bta_hf_client_sco.c
+++ b/components/bt/bluedroid/bta/hf_client/bta_hf_client_sco.c
@@ -46,7 +46,7 @@ static const tBTM_ESCO_PARAMS bta_hf_client_esco_params[] = {
BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
BTM_SCO_PKT_TYPES_MASK_NO_3_EV5),
- .retrans_effort = BTM_ESCO_RETRANS_POWER,
+ .retrans_effort = BTM_ESCO_RETRANS_OFF,
},
/* ESCO CVSD */
{
diff --git a/components/bt/bluedroid/bta/include/bta/bta_api.h b/components/bt/bluedroid/bta/include/bta/bta_api.h
index 702701bd2e..00205addc2 100644
--- a/components/bt/bluedroid/bta/include/bta/bta_api.h
+++ b/components/bt/bluedroid/bta/include/bta/bta_api.h
@@ -631,10 +631,13 @@ typedef UINT8 tBTA_SIG_STRENGTH_MASK;
#define BTA_DM_SP_RMT_OOB_EXT_EVT 23 /* Simple Pairing Remote OOB Extended Data request. */
#define BTA_DM_BLE_AUTH_CMPL_EVT 24 /* BLE Auth complete */
// btla-specific --
-#define BTA_DM_DEV_UNPAIRED_EVT 25
+#define BTA_DM_DEV_UNPAIRED_EVT 25 /* BT unpair event */
#define BTA_DM_HW_ERROR_EVT 26 /* BT Chip H/W error */
#define BTA_DM_LE_FEATURES_READ 27 /* Cotroller specific LE features are read */
#define BTA_DM_ENER_INFO_READ 28 /* Energy info read */
+#define BTA_DM_BLE_DEV_UNPAIRED_EVT 29 /* BLE unpair event */
+#define BTA_DM_SP_KEY_REQ_EVT 30 /* Simple Pairing Passkey request */
+
typedef UINT8 tBTA_DM_SEC_EVT;
/* Structure associated with BTA_DM_ENABLE_EVT */
@@ -867,6 +870,13 @@ typedef struct {
tBTA_AUTH_REQ rmt_io_caps; /* IO Capabilities of remote device */
} tBTA_DM_SP_CFM_REQ;
+/* Structure associated with tBTA_DM_SP_KEY_REQ */
+typedef struct {
+ BD_ADDR bd_addr; /* peer address */
+ DEV_CLASS dev_class; /* peer CoD */
+ BD_NAME bd_name; /* peer device name */
+} tBTA_DM_SP_KEY_REQ;
+
enum {
BTA_SP_KEY_STARTED, /* passkey entry started */
BTA_SP_KEY_ENTERED, /* passkey digit entered */
@@ -906,23 +916,24 @@ typedef struct {
/* Union of all security callback structures */
typedef union {
- tBTA_DM_ENABLE enable; /* BTA enabled */
- tBTA_DM_PIN_REQ pin_req; /* PIN request. */
- tBTA_DM_AUTH_CMPL auth_cmpl; /* Authentication complete indication. */
- tBTA_DM_AUTHORIZE authorize; /* Authorization request. */
- tBTA_DM_LINK_UP link_up; /* ACL connection down event */
- tBTA_DM_LINK_DOWN link_down; /* ACL connection down event */
- tBTA_DM_BUSY_LEVEL busy_level; /* System busy level */
- tBTA_DM_SP_CFM_REQ cfm_req; /* user confirm request */
- tBTA_DM_SP_KEY_NOTIF key_notif; /* passkey notification */
- tBTA_DM_SP_RMT_OOB rmt_oob; /* remote oob */
- tBTA_DM_BOND_CANCEL_CMPL bond_cancel_cmpl; /* Bond Cancel Complete indication */
- tBTA_DM_SP_KEY_PRESS key_press; /* key press notification event */
- tBTA_DM_ROLE_CHG role_chg; /* role change event */
- tBTA_DM_BLE_SEC_REQ ble_req; /* BLE SMP related request */
- tBTA_DM_BLE_KEY ble_key; /* BLE SMP keys used when pairing */
- tBTA_BLE_LOCAL_ID_KEYS ble_id_keys; /* IR event */
- BT_OCTET16 ble_er; /* ER event data */
+ tBTA_DM_ENABLE enable; /* BTA enabled */
+ tBTA_DM_PIN_REQ pin_req; /* PIN request. */
+ tBTA_DM_AUTH_CMPL auth_cmpl; /* Authentication complete indication. */
+ tBTA_DM_AUTHORIZE authorize; /* Authorization request. */
+ tBTA_DM_LINK_UP link_up; /* ACL connection down event */
+ tBTA_DM_LINK_DOWN link_down; /* ACL connection down event */
+ tBTA_DM_BUSY_LEVEL busy_level; /* System busy level */
+ tBTA_DM_SP_CFM_REQ cfm_req; /* user confirm request */
+ tBTA_DM_SP_KEY_REQ key_req; /* user passkey request */
+ tBTA_DM_SP_KEY_NOTIF key_notif; /* passkey notification */
+ tBTA_DM_SP_RMT_OOB rmt_oob; /* remote oob */
+ tBTA_DM_BOND_CANCEL_CMPL bond_cancel_cmpl; /* Bond Cancel Complete indication */
+ tBTA_DM_SP_KEY_PRESS key_press; /* key press notification event */
+ tBTA_DM_ROLE_CHG role_chg; /* role change event */
+ tBTA_DM_BLE_SEC_REQ ble_req; /* BLE SMP related request */
+ tBTA_DM_BLE_KEY ble_key; /* BLE SMP keys used when pairing */
+ tBTA_BLE_LOCAL_ID_KEYS ble_id_keys; /* IR event */
+ BT_OCTET16 ble_er; /* ER event data */
} tBTA_DM_SEC;
/* Security callback */
@@ -1428,7 +1439,7 @@ extern void BTA_DmUpdateWhiteList(BOOLEAN add_remove, BD_ADDR remote_addr, tBTA
extern void BTA_DmBleReadAdvTxPower(tBTA_CMPL_CB *cmpl_cb);
-extern void BTA_DmBleReadRSSI(BD_ADDR remote_addr, tBTA_CMPL_CB *cmpl_cb);
+extern void BTA_DmBleReadRSSI(BD_ADDR remote_addr, tBTA_TRANSPORT transport, tBTA_CMPL_CB *cmpl_cb);
/*******************************************************************************
**
@@ -1601,6 +1612,18 @@ extern void BTA_DmLocalOob(void);
*******************************************************************************/
extern void BTA_DmConfirm(BD_ADDR bd_addr, BOOLEAN accept);
+/*******************************************************************************
+**
+** Function BTA_DmPasskeyReqReply
+**
+** Description This function is called to provide the passkey for
+** Simple Pairing in response to BTA_DM_SP_KEY_REQ_EVT
+**
+** Returns void
+**
+*******************************************************************************/
+extern void BTA_DmPasskeyReqReply(BOOLEAN accept, BD_ADDR bd_addr, UINT32 passkey);
+
/*******************************************************************************
**
** Function BTA_DmAddDevice
@@ -1632,7 +1655,7 @@ extern void BTA_DmAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class,
** BTA_FAIL if operation failed.
**
*******************************************************************************/
-extern tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr);
+extern tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr, tBT_TRANSPORT transport);
/*******************************************************************************
**
diff --git a/components/bt/bluedroid/bta/include/bta/bta_dm_co.h b/components/bt/bluedroid/bta/include/bta/bta_dm_co.h
index 1f1f648a9f..3d49a6987b 100644
--- a/components/bt/bluedroid/bta/include/bta/bta_dm_co.h
+++ b/components/bt/bluedroid/bta/include/bta/bta_dm_co.h
@@ -30,6 +30,20 @@
** Function Declarations
*****************************************************************************/
+/*******************************************************************************
+**
+** Function bta_dm_co_bt_set_io_cap
+**
+** Description This function is used to set IO capabilities
+**
+** Parameters bt_io_cap - IO capabilities
+**
+** @return - ESP_BT_STATUS_SUCCESS : success
+** - other : failed
+**
+*******************************************************************************/
+extern esp_err_t bta_dm_co_bt_set_io_cap(UINT8 bt_io_cap);
+
/*******************************************************************************
**
** Function bta_dm_co_io_req
diff --git a/components/bt/bluedroid/bta/include/bta/bta_gatt_api.h b/components/bt/bluedroid/bta/include/bta/bta_gatt_api.h
index 72eb3643b6..9e59917518 100644
--- a/components/bt/bluedroid/bta/include/bta/bta_gatt_api.h
+++ b/components/bt/bluedroid/bta/include/bta/bta_gatt_api.h
@@ -282,7 +282,8 @@ typedef struct {
UINT8 id;
UINT8 prop; /* used when attribute type is characteristic */
BOOLEAN is_primary; /* used when attribute type is service */
- UINT16 incl_srvc_handle; /* used when attribute type is included service */
+ UINT16 incl_srvc_s_handle; /* used when attribute type is included service */
+ UINT16 incl_srvc_e_handle; /* used when attribute type is included service */
}tBTA_GATTC_NV_ATTR;
/* callback data structure */
@@ -691,6 +692,7 @@ typedef struct
tBT_UUID uuid;
UINT16 handle;
UINT16 incl_srvc_s_handle;
+ UINT16 incl_srvc_e_handle;
tBTA_GATTC_SERVICE *owning_service; /* owning service*/
tBTA_GATTC_SERVICE *included_service;
} __attribute__((packed)) tBTA_GATTC_INCLUDED_SVC;
@@ -1096,11 +1098,12 @@ extern void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_mult
** Description Refresh the server cache of the remote device
**
** Parameters remote_bda: remote device BD address.
+** erase_flash: delete cache from nvs flash
**
** Returns void
**
*******************************************************************************/
-extern void BTA_GATTC_Refresh(BD_ADDR remote_bda);
+extern void BTA_GATTC_Refresh(BD_ADDR remote_bda, bool erase_flash);
extern void BTA_GATTC_CacheAssoc(tBTA_GATTC_IF client_if, BD_ADDR src_addr, BD_ADDR assoc_addr, BOOLEAN is_assoc);
diff --git a/components/bt/bluedroid/bta/include/bta/bta_gattc_co.h b/components/bt/bluedroid/bta/include/bta/bta_gattc_co.h
index a902a2edf2..44a0e18ef2 100644
--- a/components/bt/bluedroid/bta/include/bta/bta_gattc_co.h
+++ b/components/bt/bluedroid/bta/include/bta/bta_gattc_co.h
@@ -113,6 +113,8 @@ extern size_t bta_gattc_get_cache_attr_length(UINT8 index);
extern void bta_gattc_co_cache_addr_init(void);
+extern void bta_gattc_co_cache_addr_deinit(void);
+
extern BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda);
extern uint8_t bta_gattc_co_find_addr_in_cache(BD_ADDR bda);
diff --git a/components/bt/bluedroid/bta/include/bta/bta_gatts_co.h b/components/bt/bluedroid/bta/include/bta/bta_gatts_co.h
index 79c70c8b0e..9d81d6461d 100644
--- a/components/bt/bluedroid/bta/include/bta/bta_gatts_co.h
+++ b/components/bt/bluedroid/bta/include/bta/bta_gatts_co.h
@@ -55,7 +55,7 @@ extern void bta_gatts_co_update_handle_range(BOOLEAN is_add, tBTA_GATTS_HNDL_RAN
**
** Returns TRUE - if the request is processed successfully and
** the response is returned in p_rsp.
-** FASLE - if the request can not be processed
+** FALSE - if the request can not be processed
**
*******************************************************************************/
extern BOOLEAN bta_gatts_co_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd,
diff --git a/components/bt/bluedroid/bta/jv/bta_jv_act.c b/components/bt/bluedroid/bta/jv/bta_jv_act.c
index 12dfd13b25..f89ba3e0ba 100644
--- a/components/bt/bluedroid/bta/jv/bta_jv_act.c
+++ b/components/bt/bluedroid/bta/jv/bta_jv_act.c
@@ -22,7 +22,6 @@
*
******************************************************************************/
-#include
#include
#include
@@ -959,6 +958,14 @@ static bool create_base_record(const uint32_t sdp_handle, const char *name, cons
return FALSE;
}
+ stage = "profile_descriptor_list";
+ if (!SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_SERIAL_PORT, SPP_VERSION)){
+ APPL_TRACE_ERROR("create_base_record: failed to create base service "
+ "record, stage: %s, scn: %d, name: %s, with_obex: %d",
+ stage, channel, name, with_obex);
+ return FALSE;
+ }
+
// Add the name to the SDP record.
if (name[0] != '\0') {
stage = "service_name";
diff --git a/components/bt/bluedroid/bta/jv/include/bta_jv_int.h b/components/bt/bluedroid/bta/jv/include/bta_jv_int.h
index 4f0ce4405d..c252633141 100644
--- a/components/bt/bluedroid/bta/jv/include/bta_jv_int.h
+++ b/components/bt/bluedroid/bta/jv/include/bta_jv_int.h
@@ -37,6 +37,8 @@
** Constants
*****************************************************************************/
+#define SPP_VERSION 0x0102
+
enum {
/* these events are handled by the state machine */
BTA_JV_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_JV),
diff --git a/components/bt/bluedroid/btc/core/btc_dm.c b/components/bt/bluedroid/btc/core/btc_dm.c
index 9f6c911058..573ff31da7 100644
--- a/components/bt/bluedroid/btc/core/btc_dm.c
+++ b/components/bt/bluedroid/btc/core/btc_dm.c
@@ -182,6 +182,10 @@ static void btc_dm_remove_ble_bonding_keys(void)
static void btc_dm_save_ble_bonding_keys(void)
{
+ if(!(pairing_cb.ble.is_penc_key_rcvd || pairing_cb.ble.is_pid_key_rcvd || pairing_cb.ble.is_pcsrk_key_rcvd ||
+ pairing_cb.ble.is_lenc_key_rcvd || pairing_cb.ble.is_lcsrk_key_rcvd || pairing_cb.ble.is_lidk_key_rcvd)) {
+ return ;
+ }
bt_bdaddr_t bd_addr;
bdcpy(bd_addr.address, pairing_cb.bd_addr);
@@ -344,7 +348,7 @@ static void btc_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
case HCI_ERR_INSUFFCIENT_SECURITY:
case HCI_ERR_PEER_USER:
case HCI_ERR_UNSPECIFIED:
- BTC_TRACE_DEBUG(" %s() Authentication fail reason %d",
+ BTC_TRACE_ERROR(" %s() Authentication fail reason %d",
__FUNCTION__, p_auth_cmpl->fail_reason);
/* if autopair attempts are more than 1, or not attempted */
status = BT_STATUS_AUTH_FAILURE;
@@ -353,7 +357,7 @@ static void btc_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
status = BT_STATUS_FAIL;
}
}
-#if (BTC_GAP_BT_INCLUDED == TRUE)
+#if (BTC_GAP_BT_INCLUDED == TRUE && BT_SSP_INCLUDED == TRUE)
esp_bt_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
@@ -368,13 +372,80 @@ static void btc_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
sizeof(esp_bt_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
- BTC_TRACE_DEBUG("%s btc_transfer_context failed\n", __func__);
+ BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
-#endif /* BTC_GAP_BT_INCLUDED == TRUE */
+#endif /// BTC_GAP_BT_INCLUDED == TRUE && BT_SSP_INCLUDED == TRUE
(void) status;
}
+#if (BT_SSP_INCLUDED == TRUE)
+static void btc_dm_sp_cfm_req_evt(tBTA_DM_SP_CFM_REQ *p_cfm_req)
+{
+ if (p_cfm_req->just_works) {
+ // just work, not show to users.
+ BTA_DmConfirm(p_cfm_req->bd_addr, true);
+ return;
+ }
+
+ esp_bt_gap_cb_param_t param;
+ bt_status_t ret;
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_GAP_BT;
+ msg.act = BTC_GAP_BT_CFM_REQ_EVT;
+ param.cfm_req.num_val = p_cfm_req->num_val;
+ memcpy(param.cfm_req.bda, p_cfm_req->bd_addr, ESP_BD_ADDR_LEN);
+
+ ret = btc_transfer_context(&msg, ¶m,
+ sizeof(esp_bt_gap_cb_param_t), NULL);
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+ }
+
+}
+
+static void btc_dm_sp_key_notif_evt(tBTA_DM_SP_KEY_NOTIF *p_key_notif)
+{
+ esp_bt_gap_cb_param_t param;
+ bt_status_t ret;
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_GAP_BT;
+ msg.act = BTC_GAP_BT_KEY_NOTIF_EVT;
+ param.key_notif.passkey = p_key_notif->passkey;
+ memcpy(param.key_notif.bda, p_key_notif->bd_addr, ESP_BD_ADDR_LEN);
+
+ ret = btc_transfer_context(&msg, ¶m,
+ sizeof(esp_bt_gap_cb_param_t), NULL);
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+ }
+
+}
+
+static void btc_dm_sp_key_req_evt(tBTA_DM_SP_KEY_REQ *p_key_req)
+{
+ esp_bt_gap_cb_param_t param;
+ bt_status_t ret;
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_GAP_BT;
+ msg.act = BTC_GAP_BT_KEY_REQ_EVT;
+ memcpy(param.key_req.bda, p_key_req->bd_addr, ESP_BD_ADDR_LEN);
+
+ ret = btc_transfer_context(&msg, ¶m,
+ sizeof(esp_bt_gap_cb_param_t), NULL);
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+ }
+}
+#endif ///BT_SSP_INCLUDED == TRUE
+
+
tBTA_SERVICE_MASK btc_get_enabled_services_mask(void)
{
return btc_enabled_services;
@@ -484,21 +555,52 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
break;
}
case BTA_DM_PIN_REQ_EVT:
+ BTC_TRACE_DEBUG("BTA_DM_PIN_REQ_EVT");
break;
case BTA_DM_AUTH_CMPL_EVT:
btc_dm_auth_cmpl_evt(&p_data->auth_cmpl);
break;
case BTA_DM_BOND_CANCEL_CMPL_EVT:
- case BTA_DM_SP_CFM_REQ_EVT:
- case BTA_DM_SP_KEY_NOTIF_EVT:
+ BTC_TRACE_DEBUG("BTA_DM_BOND_CANCEL_CMPL_EVT");
break;
+#if (BT_SSP_INCLUDED == TRUE)
+ case BTA_DM_SP_CFM_REQ_EVT:
+ btc_dm_sp_cfm_req_evt(&p_data->cfm_req);
+ break;
+ case BTA_DM_SP_KEY_NOTIF_EVT:
+ btc_dm_sp_key_notif_evt(&p_data->key_notif);
+ break;
+ case BTA_DM_SP_KEY_REQ_EVT:
+ btc_dm_sp_key_req_evt(&p_data->key_req);
+ break;
+ case BTA_DM_SP_RMT_OOB_EVT:
+ BTC_TRACE_DEBUG("BTA_DM_SP_RMT_OOB_EVT");
+ break;
+ case BTA_DM_SP_KEYPRESS_EVT:
+ BTC_TRACE_DEBUG("BTA_DM_SP_KEYPRESS_EVT");
+ break;
+#endif ///BT_SSP_INCLUDED == TRUE
+
case BTA_DM_DEV_UNPAIRED_EVT: {
#if (SMP_INCLUDED == TRUE)
bt_bdaddr_t bd_addr;
- rsp_app = true;
BTC_TRACE_DEBUG("BTA_DM_DEV_UNPAIRED_EVT");
memcpy(bd_addr.address, p_data->link_down.bd_addr, sizeof(BD_ADDR));
btm_set_bond_type_dev(p_data->link_down.bd_addr, BOND_TYPE_UNKNOWN);
+ if (p_data->link_down.status == HCI_SUCCESS) {
+ //remove the bonded key in the config and nvs flash.
+ btc_storage_remove_bonded_device(&bd_addr);
+ }
+#endif /* #if (SMP_INCLUDED == TRUE) */
+ break;
+ }
+ case BTA_DM_BLE_DEV_UNPAIRED_EVT: {
+#if (SMP_INCLUDED == TRUE)
+ bt_bdaddr_t bd_addr;
+ rsp_app = true;
+ BTC_TRACE_DEBUG("BTA_DM_BLE_DEV_UNPAIRED_EVT");
+ memcpy(bd_addr.address, p_data->link_down.bd_addr, sizeof(BD_ADDR));
+ btm_set_bond_type_dev(p_data->link_down.bd_addr, BOND_TYPE_UNKNOWN);
param.remove_bond_dev_cmpl.status = ESP_BT_STATUS_FAIL;
if (p_data->link_down.status == HCI_SUCCESS) {
@@ -675,8 +777,6 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
case BTA_DM_AUTHORIZE_EVT:
case BTA_DM_SIG_STRENGTH_EVT:
- case BTA_DM_SP_RMT_OOB_EVT:
- case BTA_DM_SP_KEYPRESS_EVT:
case BTA_DM_ROLE_CHG_EVT:
BTC_TRACE_DEBUG( "btc_dm_sec_cback : unhandled event (%d)\n", msg->act );
break;
diff --git a/components/bt/bluedroid/btc/core/btc_task.c b/components/bt/bluedroid/btc/core/btc_task.c
index b8afbb5814..1022e770d1 100644
--- a/components/bt/bluedroid/btc/core/btc_task.c
+++ b/components/bt/bluedroid/btc/core/btc_task.c
@@ -170,6 +170,9 @@ int btc_init(void)
return BT_STATUS_NOMEM;
}
btc_gap_callback_init();
+#if SCAN_QUEUE_CONGEST_CHECK
+ btc_adv_list_init();
+#endif
/* TODO: initial the profile_tab */
return BT_STATUS_SUCCESS;
}
@@ -178,7 +181,18 @@ void btc_deinit(void)
{
vTaskDelete(xBtcTaskHandle);
vQueueDelete(xBtcQueue);
-
+#if SCAN_QUEUE_CONGEST_CHECK
+ btc_adv_list_deinit();
+#endif
xBtcTaskHandle = NULL;
xBtcQueue = 0;
}
+
+bool btc_check_queue_is_congest(void)
+{
+ UBaseType_t wait_size = uxQueueMessagesWaiting(xBtcQueue);
+ if(wait_size >= QUEUE_CONGEST_SIZE) {
+ return true;
+ }
+ return false;
+}
diff --git a/components/bt/bluedroid/btc/include/btc/btc_task.h b/components/bt/bluedroid/btc/include/btc/btc_task.h
index f644e865a6..5813c52178 100644
--- a/components/bt/bluedroid/btc/include/btc/btc_task.h
+++ b/components/bt/bluedroid/btc/include/btc/btc_task.h
@@ -28,6 +28,11 @@ typedef struct btc_msg {
void *arg; //param for btc function or function param
} btc_msg_t;
+typedef struct btc_adv_packet {
+ uint8_t addr[6];
+ uint8_t addr_type;
+} btc_adv_packet_t;
+
typedef enum {
BTC_SIG_API_CALL = 0, // APP TO STACK
BTC_SIG_API_CB, // STACK TO APP
@@ -72,5 +77,6 @@ bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg
int btc_init(void);
void btc_deinit(void);
+bool btc_check_queue_is_congest(void);
#endif /* __BTC_TASK_H__ */
diff --git a/components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c b/components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c
index 2722b3e9bd..faf23eefc7 100644
--- a/components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c
+++ b/components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c
@@ -87,8 +87,8 @@ enum {
but due to link flow control or thread preemption in lower
layers we might need to temporarily buffer up data */
-/* 5 frames is equivalent to 6.89*5*2.9 ~= 100 ms @ 44.1 khz, 20 ms mediatick */
-#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (5)
+/* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
+#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (18)
typedef struct {
UINT16 num_frames_to_be_processed;
@@ -763,7 +763,7 @@ static void btc_a2dp_sink_thread_init(UNUSED_ATTR void *context)
btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_ON;
- btc_aa_snk_cb.RxSbcQ = fixed_queue_new(SIZE_MAX);
+ btc_aa_snk_cb.RxSbcQ = fixed_queue_new(QUEUE_SIZE_MAX);
btc_a2dp_control_init();
}
diff --git a/components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c b/components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c
index da5ff32b96..590c382ffe 100644
--- a/components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c
+++ b/components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c
@@ -1616,7 +1616,7 @@ static void btc_a2dp_source_thread_init(UNUSED_ATTR void *context)
btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_ON;
- btc_aa_src_cb.TxAaQ = fixed_queue_new(SIZE_MAX);
+ btc_aa_src_cb.TxAaQ = fixed_queue_new(QUEUE_SIZE_MAX);
btc_a2dp_control_init();
}
diff --git a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c
index c3937cf652..c8951db4c4 100644
--- a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c
+++ b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c
@@ -28,9 +28,23 @@
#include "btc/btc_ble_storage.h"
#include "btc/btc_dm.h"
#include "btc/btc_util.h"
+#include "osi/mutex.h"
static tBTA_BLE_ADV_DATA gl_bta_adv_data;
static tBTA_BLE_ADV_DATA gl_bta_scan_rsp_data;
+#if SCAN_QUEUE_CONGEST_CHECK
+static list_t *adv_filter_list;
+static osi_mutex_t adv_list_lock;
+bool btc_check_adv_list(uint8_t * addr, uint8_t addr_type);
+uint32_t btc_get_adv_list_length(void);
+void btc_adv_list_refresh(void);
+void btc_adv_list_lock(void);
+void btc_adv_list_unlock(void);
+static uint16_t btc_adv_list_count = 0;
+
+#define BTC_ADV_LIST_MAX_LENGTH 50
+#define BTC_ADV_LIST_MAX_COUNT 200
+#endif
static inline void btc_gap_ble_cb_to_app(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
@@ -510,6 +524,19 @@ static void btc_search_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data
param.scan_rst.search_evt = event;
switch (event) {
case BTA_DM_INQ_RES_EVT: {
+#if SCAN_QUEUE_CONGEST_CHECK
+ if(btc_check_queue_is_congest()) {
+ BTC_TRACE_DEBUG("BtcQueue is congested");
+ if(btc_get_adv_list_length() > BTC_ADV_LIST_MAX_LENGTH || btc_adv_list_count > BTC_ADV_LIST_MAX_COUNT) {
+ btc_adv_list_refresh();
+ btc_adv_list_count = 0;
+ }
+ if(btc_check_adv_list(p_data->inq_res.bd_addr, p_data->inq_res.ble_addr_type)) {
+ return;
+ }
+ }
+ btc_adv_list_count ++;
+#endif
bdcpy(param.scan_rst.bda, p_data->inq_res.bd_addr);
param.scan_rst.dev_type = p_data->inq_res.device_type;
param.scan_rst.rssi = p_data->inq_res.rssi;
@@ -585,6 +612,9 @@ static void btc_stop_scan_callback(tBTA_STATUS status)
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
+#if SCAN_QUEUE_CONGEST_CHECK
+ btc_adv_list_refresh();
+#endif
}
void btc_update_conn_param_callback (UINT8 status, BD_ADDR bd_addr, tBTM_LE_UPDATE_CONN_PRAMS *update_conn_params)
@@ -725,6 +755,9 @@ static void btc_ble_start_scanning(uint32_t duration,
tBTA_START_STOP_SCAN_CMPL_CBACK *start_scan_cb)
{
if ((results_cb != NULL) && (start_scan_cb != NULL)) {
+#if SCAN_QUEUE_CONGEST_CHECK
+ btc_adv_list_refresh();
+#endif
//Start scan the device
BTA_DmBleScan(true, duration, results_cb, start_scan_cb);
} else {
@@ -1018,7 +1051,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
BTA_DmUpdateWhiteList(arg->update_white_list.add_remove, arg->update_white_list.remote_bda, btc_add_whitelist_complete_callback);
break;
case BTC_GAP_BLE_ACT_READ_RSSI:
- BTA_DmBleReadRSSI(arg->read_rssi.remote_addr, btc_read_ble_rssi_cmpl_callback);
+ BTA_DmBleReadRSSI(arg->read_rssi.remote_addr, BTA_TRANSPORT_LE, btc_read_ble_rssi_cmpl_callback);
break;
case BTC_GAP_BLE_ACT_SET_CONN_PARAMS:
BTA_DmSetBlePrefConnParams(arg->set_conn_params.bd_addr, arg->set_conn_params.min_conn_int,
@@ -1108,7 +1141,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
case BTC_GAP_BLE_REMOVE_BOND_DEV_EVT: {
BD_ADDR bd_addr;
memcpy(bd_addr, arg->remove_bond_device.bd_addr, sizeof(BD_ADDR));
- BTA_DmRemoveDevice(bd_addr);
+ BTA_DmRemoveDevice(bd_addr, BT_TRANSPORT_LE);
break;
}
#endif ///SMP_INCLUDED == TRUE
@@ -1134,3 +1167,99 @@ void btc_gap_ble_deinit(void)
btc_cleanup_adv_data(&gl_bta_adv_data);
btc_cleanup_adv_data(&gl_bta_scan_rsp_data);
}
+
+#if SCAN_QUEUE_CONGEST_CHECK
+void btc_adv_list_free(void *data)
+{
+ osi_free(data);
+}
+
+void btc_adv_list_init(void)
+{
+ osi_mutex_new(&adv_list_lock);
+ adv_filter_list = list_new(btc_adv_list_free);
+}
+
+void btc_adv_list_deinit(void)
+{
+ osi_mutex_free(&adv_list_lock);
+ if(adv_filter_list) {
+ list_free(adv_filter_list);
+ adv_filter_list = NULL;
+ }
+}
+void btc_adv_list_add_packet(void * data)
+{
+ if(!data) {
+ BTC_TRACE_ERROR("%s data is NULL", __func__);
+ return;
+ }
+ btc_adv_list_lock();
+ list_prepend(adv_filter_list, data);
+ btc_adv_list_unlock();
+}
+
+uint32_t btc_get_adv_list_length(void)
+{
+ if(!adv_filter_list) {
+ BTC_TRACE_ERROR("%s adv_filter_list is NULL", __func__);
+ return 0;
+ }
+ btc_adv_list_lock();
+ size_t length = list_length(adv_filter_list);
+ btc_adv_list_unlock();
+
+ return length;
+}
+
+void btc_adv_list_refresh(void)
+{
+ if(!adv_filter_list) {
+ BTC_TRACE_ERROR("%s adv_filter_list is NULL", __func__);
+ return ;
+ }
+ btc_adv_list_lock();
+ list_clear(adv_filter_list);
+ btc_adv_list_unlock();
+}
+
+bool btc_check_adv_list(uint8_t * addr, uint8_t addr_type)
+{
+ bool found = false;
+ if(!adv_filter_list || !addr) {
+ BTC_TRACE_ERROR("%s adv_filter_list is NULL", __func__);
+ return found;
+ }
+
+ btc_adv_list_lock();
+ for (const list_node_t *node = list_begin(adv_filter_list); node != list_end(adv_filter_list); node = list_next(node)) {
+ btc_adv_packet_t *packet = (btc_adv_packet_t *)list_node(node);
+ if(!bdcmp(addr, packet->addr) && packet->addr_type == addr_type) {
+ found = true;
+ break;
+ }
+ }
+ btc_adv_list_unlock();
+ if(!found) {
+ btc_adv_packet_t *adv_packet = osi_malloc(sizeof(btc_adv_packet_t));
+ if(adv_packet) {
+ adv_packet->addr_type = addr_type;
+ bdcpy(adv_packet->addr, addr);
+ btc_adv_list_add_packet(adv_packet);
+ } else {
+ BTC_TRACE_ERROR("%s adv_packet malloc failed", __func__);
+ }
+ }
+ return found;
+}
+
+void btc_adv_list_lock(void)
+{
+ osi_mutex_lock(&adv_list_lock, OSI_MUTEX_MAX_TIMEOUT);
+}
+
+void btc_adv_list_unlock(void)
+{
+ osi_mutex_unlock(&adv_list_lock);
+}
+#endif
diff --git a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c
index c6a5a0894a..1b6985c353 100644
--- a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c
+++ b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c
@@ -23,6 +23,7 @@
#include "btc/btc_manage.h"
#include "btc/btc_util.h"
#include "osi/allocator.h"
+#include "bta/bta_dm_co.h"
#if (BTC_GAP_BT_INCLUDED == TRUE)
@@ -151,7 +152,7 @@ static void search_devices_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src)
switch (p_dest_data->event) {
case BTA_DM_INQ_RES_EVT: {
if (p_src_data->p_data->inq_res.p_eir) {
- p_dest_data->p_data->inq_res.p_eir = (UINT8 *)(p_dest_data->p_data + sizeof(tBTA_DM_SEARCH));
+ p_dest_data->p_data->inq_res.p_eir = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
memcpy(p_dest_data->p_data->inq_res.p_eir, p_src_data->p_data->inq_res.p_eir, HCI_EXT_INQ_RESPONSE_LEN);
}
}
@@ -159,7 +160,7 @@ static void search_devices_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src)
case BTA_DM_DISC_RES_EVT: {
if (p_src_data->p_data->disc_res.raw_data_size && p_src_data->p_data->disc_res.p_raw_data) {
- p_dest_data->p_data->disc_res.p_raw_data = (UINT8 *)(p_dest_data->p_data + sizeof(tBTA_DM_SEARCH));
+ p_dest_data->p_data->disc_res.p_raw_data = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
memcpy(p_dest_data->p_data->disc_res.p_raw_data,
p_src_data->p_data->disc_res.p_raw_data,
p_src_data->p_data->disc_res.raw_data_size);
@@ -194,7 +195,7 @@ static void search_service_record_copy_cb(btc_msg_t *msg, void *p_dest, void *p_
switch (p_dest_data->event) {
case BTA_DM_DISC_RES_EVT: {
if (p_src_data->p_data->disc_res.p_raw_data && p_src_data->p_data->disc_res.raw_data_size > 0) {
- p_dest_data->p_data->disc_res.p_raw_data = (UINT8 *)(p_dest_data->p_data + sizeof(tBTA_DM_SEARCH));
+ p_dest_data->p_data->disc_res.p_raw_data = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
memcpy(p_dest_data->p_data->disc_res.p_raw_data,
p_src_data->p_data->disc_res.p_raw_data,
p_src_data->p_data->disc_res.raw_data_size);
@@ -478,7 +479,7 @@ static void btc_gap_bt_search_services(char *p_param)
param.rmt_srvcs.stat = ESP_BT_STATUS_FAIL;
if (p_data->p_data->disc_res.result == BTA_SUCCESS) {
- uuid_list = malloc(sizeof(esp_bt_uuid_t) * p_data->p_data->disc_res.num_uuids);
+ uuid_list = osi_malloc(sizeof(esp_bt_uuid_t) * p_data->p_data->disc_res.num_uuids);
if (uuid_list) {
param.rmt_srvcs.stat = ESP_BT_STATUS_SUCCESS;
param.rmt_srvcs.num_uuids = p_data->p_data->disc_res.num_uuids;
@@ -566,7 +567,7 @@ static void search_services_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src)
case BTA_DM_DISC_RES_EVT: {
if (p_src_data->p_data->disc_res.result == BTA_SUCCESS) {
if (p_src_data->p_data->disc_res.num_uuids > 0) {
- p_dest_data->p_data->disc_res.p_uuid_list = (UINT8 *)(p_dest_data->p_data + sizeof(tBTA_DM_SEARCH));
+ p_dest_data->p_data->disc_res.p_uuid_list = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
memcpy(p_dest_data->p_data->disc_res.p_uuid_list, p_src_data->p_data->disc_res.p_uuid_list,
p_src_data->p_data->disc_res.num_uuids * MAX_UUID_SIZE);
osi_free(p_src_data->p_data->disc_res.p_uuid_list);
@@ -632,20 +633,116 @@ static void btc_gap_bt_read_rssi_delta_cmpl_callback(void *p_data)
static void btc_gap_bt_read_rssi_delta(btc_gap_bt_args_t *arg)
{
- BTA_DmBleReadRSSI(arg->read_rssi_delta.bda.address, btc_gap_bt_read_rssi_delta_cmpl_callback);
+ BTA_DmBleReadRSSI(arg->read_rssi_delta.bda.address, BTA_TRANSPORT_BR_EDR, btc_gap_bt_read_rssi_delta_cmpl_callback);
}
-esp_err_t btc_gap_bt_remove_bond_device(btc_gap_bt_args_t *arg)
+static esp_err_t btc_gap_bt_remove_bond_device(btc_gap_bt_args_t *arg)
{
BD_ADDR bd_addr;
memcpy(bd_addr, arg->rm_bond_device.bda.address, sizeof(BD_ADDR));
- if(BTA_DmRemoveDevice(bd_addr) == BTA_SUCCESS){
- btc_storage_remove_bonded_device(&(arg->rm_bond_device.bda));
+ if(BTA_DmRemoveDevice(bd_addr, BT_TRANSPORT_BR_EDR) == BTA_SUCCESS){
return ESP_BT_STATUS_SUCCESS;
}
return ESP_BT_STATUS_FAIL;
}
+#if (BT_SSP_INCLUDED == TRUE)
+static esp_err_t btc_gap_bt_set_security_param(btc_gap_bt_args_t *arg)
+{
+ esp_err_t ret;
+ switch(arg->set_security_param.param_type) {
+ case ESP_BT_SP_IOCAP_MODE:{
+ uint8_t iocap = 0;
+ uint8_t *p = arg->set_security_param.value;
+ STREAM_TO_UINT8(iocap, p);
+ ret = bta_dm_co_bt_set_io_cap(iocap);
+ break;
+ }
+ default:
+ ret = ESP_BT_STATUS_FAIL;
+ break;
+ }
+ return ret;
+}
+
+static void btc_gap_bt_ssp_passkey_reply(btc_gap_bt_args_t *arg)
+{
+ BTA_DmPasskeyReqReply(arg->passkey_reply.accept, arg->passkey_reply.bda.address, arg->passkey_reply.passkey);
+}
+
+static void btc_gap_bt_ssp_confirm(btc_gap_bt_args_t *arg)
+{
+ BTA_DmConfirm(arg->confirm_reply.bda.address, arg->confirm_reply.accept);
+
+}
+
+#endif ///BT_SSP_INCLUDED == TRUE
+
+void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
+{
+ switch (msg->act) {
+ case BTC_GAP_BT_ACT_SET_SCAN_MODE:
+ case BTC_GAP_BT_ACT_START_DISCOVERY:
+ case BTC_GAP_BT_ACT_CANCEL_DISCOVERY:
+ case BTC_GAP_BT_ACT_GET_REMOTE_SERVICES:
+ case BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD:
+ case BTC_GAP_BT_ACT_SET_COD:
+ case BTC_GAP_BT_ACT_READ_RSSI_DELTA:
+ case BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE:
+ break;
+#if (BT_SSP_INCLUDED == TRUE)
+ case BTC_GAP_BT_ACT_PASSKEY_REPLY:
+ case BTC_GAP_BT_ACT_CONFIRM_REPLY:
+ break;
+ case BTC_GAP_BT_ACT_SET_SECURITY_PARAM:{
+ btc_gap_bt_args_t *src = (btc_gap_bt_args_t *)p_src;
+ btc_gap_bt_args_t *dst = (btc_gap_bt_args_t *) p_dest;
+ uint8_t length = 0;
+ if (src->set_security_param.value) {
+ length = dst->set_security_param.len;
+ dst->set_security_param.value = osi_malloc(length);
+ if (dst->set_security_param.value != NULL) {
+ memcpy(dst->set_security_param.value, src->set_security_param.value, length);
+ } else {
+ BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
+ }
+ }
+ break;
+ }
+#endif ///BT_SSP_INCLUDED == TRUE
+ default:
+ BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act);
+ break;
+ }
+}
+
+void btc_gap_bt_arg_deep_free(btc_msg_t *msg)
+{
+ btc_gap_bt_args_t *arg = (btc_gap_bt_args_t *)msg->arg;
+ switch (msg->act) {
+ case BTC_GAP_BT_ACT_SET_SCAN_MODE:
+ case BTC_GAP_BT_ACT_START_DISCOVERY:
+ case BTC_GAP_BT_ACT_CANCEL_DISCOVERY:
+ case BTC_GAP_BT_ACT_GET_REMOTE_SERVICES:
+ case BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD:
+ case BTC_GAP_BT_ACT_SET_COD:
+ case BTC_GAP_BT_ACT_READ_RSSI_DELTA:
+ case BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE:
+ break;
+#if (BT_SSP_INCLUDED == TRUE)
+ case BTC_GAP_BT_ACT_PASSKEY_REPLY:
+ case BTC_GAP_BT_ACT_CONFIRM_REPLY:
+ break;
+ case BTC_GAP_BT_ACT_SET_SECURITY_PARAM:
+ osi_free(arg->set_security_param.value);
+ break;
+#endif ///BT_SSP_INCLUDED == TRUE
+ default:
+ BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act);
+ break;
+ }
+}
+
void btc_gap_bt_call_handler(btc_msg_t *msg)
{
btc_gap_bt_args_t *arg = (btc_gap_bt_args_t *)msg->arg;
@@ -683,10 +780,25 @@ void btc_gap_bt_call_handler(btc_msg_t *msg)
btc_gap_bt_remove_bond_device(msg->arg);
break;
}
+#if (BT_SSP_INCLUDED == TRUE)
+ case BTC_GAP_BT_ACT_SET_SECURITY_PARAM:{
+ btc_gap_bt_set_security_param(arg);
+ break;
+ }
+ case BTC_GAP_BT_ACT_PASSKEY_REPLY:{
+ btc_gap_bt_ssp_passkey_reply(arg);
+ break;
+ }
+ case BTC_GAP_BT_ACT_CONFIRM_REPLY:{
+ btc_gap_bt_ssp_confirm(arg);
+ break;
+ }
+#endif ///BT_SSP_INCLUDED == TRUE
+
default:
break;
}
-
+ btc_gap_bt_arg_deep_free(msg);
return;
}
@@ -715,7 +827,12 @@ void btc_gap_bt_cb_deep_free(btc_msg_t *msg)
osi_free(((tBTA_DM_SEARCH_PARAM *) (msg->arg)) ->p_data);
break;
case BTC_GAP_BT_READ_RSSI_DELTA_EVT:
+#if (BT_SSP_INCLUDED == TRUE)
case BTC_GAP_BT_AUTH_CMPL_EVT:
+ case BTC_GAP_BT_CFM_REQ_EVT:
+ case BTC_GAP_BT_KEY_NOTIF_EVT:
+ case BTC_GAP_BT_KEY_REQ_EVT:
+#endif ///BT_SSP_INCLUDED == TRUE
break;
default:
BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
@@ -742,10 +859,24 @@ void btc_gap_bt_cb_handler(btc_msg_t *msg)
btc_gap_bt_cb_to_app(ESP_BT_GAP_READ_RSSI_DELTA_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
break;
}
+#if (BT_SSP_INCLUDED == TRUE)
case BTC_GAP_BT_AUTH_CMPL_EVT:{
btc_gap_bt_cb_to_app(ESP_BT_GAP_AUTH_CMPL_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
break;
}
+ case BTC_GAP_BT_CFM_REQ_EVT:{
+ btc_gap_bt_cb_to_app(ESP_BT_GAP_CFM_REQ_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
+ break;
+ }
+ case BTC_GAP_BT_KEY_NOTIF_EVT:{
+ btc_gap_bt_cb_to_app(ESP_BT_GAP_KEY_NOTIF_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
+ break;
+ }
+ case BTC_GAP_BT_KEY_REQ_EVT:{
+ btc_gap_bt_cb_to_app(ESP_BT_GAP_KEY_REQ_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
+ break;
+ }
+#endif ///BT_SSP_INCLUDED == TRUE
default:
BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
break;
diff --git a/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c b/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c
index 0694b990f0..bb7d6cbbdf 100644
--- a/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c
+++ b/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c
@@ -331,6 +331,7 @@ esp_gatt_status_t btc_ble_gattc_get_service(uint16_t conn_id, esp_bt_uuid_t *svc
if (bta_uuid) {
osi_free(bta_uuid);
}
+ *count = 0;
return status;
} else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)svc_num, ESP_GATT_DB_PRIMARY_SERVICE, offset, (void *)result, db);
@@ -362,6 +363,7 @@ esp_gatt_status_t btc_ble_gattc_get_all_char(uint16_t conn_id,
if (db) {
osi_free(db);
}
+ *count = 0;
return status;
} else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)char_num, ESP_GATT_DB_CHARACTERISTIC, offset, (void *)result, db);
@@ -389,6 +391,7 @@ esp_gatt_status_t btc_ble_gattc_get_all_descr(uint16_t conn_id,
if (db) {
osi_free(db);
}
+ *count = 0;
return status;
} else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)descr_num, ESP_GATT_DB_DESCRIPTOR, offset, (void *)result, db);
@@ -420,6 +423,7 @@ esp_gatt_status_t btc_ble_gattc_get_char_by_uuid(uint16_t conn_id,
if (db) {
osi_free(db);
}
+ *count = 0;
return status;
} else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)char_num, ESP_GATT_DB_CHARACTERISTIC, 0, (void *)result, db);
@@ -456,6 +460,7 @@ esp_gatt_status_t btc_ble_gattc_get_descr_by_uuid(uint16_t conn_id,
if (db) {
osi_free(db);
}
+ *count = 0;
return status;
} else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)descr_num, ESP_GATT_DB_DESCRIPTOR, 0, (void *)result, db);
@@ -487,6 +492,7 @@ esp_gatt_status_t btc_ble_gattc_get_descr_by_char_handle(uint16_t conn_id,
if (db) {
osi_free(db);
}
+ *count = 0;
return status;
} else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)descr_num, ESP_GATT_DB_DESCRIPTOR, 0, (void *)result, db);
@@ -524,6 +530,7 @@ esp_gatt_status_t btc_ble_gattc_get_include_service(uint16_t conn_id,
if (db) {
osi_free(db);
}
+ *count = 0;
return status;
}else {
btc_gattc_fill_gatt_db_conversion(*count, (uint16_t)incl_num, ESP_GATT_DB_INCLUDED_SERVICE, 0, (void *)result, db);
@@ -566,6 +573,7 @@ esp_gatt_status_t btc_ble_gattc_get_db(uint16_t conn_id, uint16_t start_handle,
if (get_db) {
osi_free(get_db);
}
+ *count = 0;
return ESP_GATT_NOT_FOUND;
}
@@ -579,7 +587,7 @@ esp_gatt_status_t btc_ble_gattc_get_db(uint16_t conn_id, uint16_t start_handle,
btc128_to_bta_uuid(&bta_uuid, get_db[i].uuid.uu);
bta_to_btc_uuid(&db[i].uuid, &bta_uuid);
}
- *count = num;
+ *count = db_size;
//don't forget to free the db buffer after used.
if (get_db) {
osi_free(get_db);
@@ -738,7 +746,7 @@ void btc_gattc_call_handler(btc_msg_t *msg)
btc_gattc_unreg_for_notify(arg);
break;
case BTC_GATTC_ACT_CACHE_REFRESH:
- BTA_GATTC_Refresh(arg->cache_refresh.remote_bda);
+ BTA_GATTC_Refresh(arg->cache_refresh.remote_bda, true);
break;
case BTC_GATTC_ACT_CACHE_ASSOC:
BTA_GATTC_CacheAssoc(arg->cache_assoc.gattc_if,
diff --git a/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c b/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c
index 74ae46a6ed..fc043914eb 100644
--- a/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c
+++ b/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c
@@ -506,6 +506,8 @@ static void btc_gatts_cb_param_copy_req(btc_msg_t *msg, void *p_dest, void *p_sr
if (p_dest_data->req_data.p_data != NULL) {
memcpy(p_dest_data->req_data.p_data, p_src_data->req_data.p_data,
sizeof(tBTA_GATTS_REQ_DATA));
+ } else {
+ BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
}
break;
@@ -759,6 +761,9 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
param.write.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id);
param.write.trans_id = p_data->req_data.trans_id;
memcpy(param.write.bda, p_data->req_data.remote_bda, ESP_BD_ADDR_LEN);
+ if (p_data->req_data.p_data == NULL) {
+ break;
+ }
param.write.handle = p_data->req_data.p_data->write_req.handle;
param.write.offset = p_data->req_data.p_data->write_req.offset;
param.write.need_rsp = p_data->req_data.p_data->write_req.need_rsp;
@@ -775,6 +780,9 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
param.exec_write.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id);
param.exec_write.trans_id = p_data->req_data.trans_id;
memcpy(param.exec_write.bda, p_data->req_data.remote_bda, ESP_BD_ADDR_LEN);
+ if (p_data->req_data.p_data == NULL) {
+ break;
+ }
param.exec_write.exec_write_flag = p_data->req_data.p_data->exec_write;
btc_gatts_cb_to_app(ESP_GATTS_EXEC_WRITE_EVT, gatts_if, ¶m);
diff --git a/components/bt/bluedroid/btc/profile/std/hid_le/hid_le_prf.c b/components/bt/bluedroid/btc/profile/std/hid_le/hid_le_prf.c
deleted file mode 100644
index 6f54bd4caf..0000000000
--- a/components/bt/bluedroid/btc/profile/std/hid_le/hid_le_prf.c
+++ /dev/null
@@ -1,638 +0,0 @@
-#include
-// Copyright 2015-2016 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.
-
-#include "hid_le_prf.h"
-#include "prf_defs.h"
-
-#if (HIDD_LE_PROFILE_CFG)
-hidd_le_env_t hidd_le_env;
-
-#define HI_UINT16(a) (((a) >> 8) & 0xFF)
-#define LO_UINT16(a) ((a) & 0xFF)
-
-
-// HID Information characteristic value
-static const uint8_t hidInfo[HID_INFORMATION_LEN] = {
- LO_UINT16(0x0111), HI_UINT16(0x0111), // bcdHID (USB HID version)
- 0x00, // bCountryCode
- HID_KBD_FLAGS // Flags
-};
-
-// HID Report Map characteristic value
-// Keyboard report descriptor (using format for Boot interface descriptor)
-static const uint8_t hidReportMap[] = {
- 0x05, 0x01, // Usage Page (Generic Desktop)
- 0x09, 0x02, // Usage (Mouse)
- 0xA1, 0x01, // Collection (Application)
- 0x85, 0x01, // Report Id (1)
- 0x09, 0x01, // Usage (Pointer)
- 0xA1, 0x00, // Collection (Physical)
- 0x05, 0x09, // Usage Page (Buttons)
- 0x19, 0x01, // Usage Minimum (01) - Button 1
- 0x29, 0x03, // Usage Maximum (03) - Button 3
- 0x15, 0x00, // Logical Minimum (0)
- 0x25, 0x01, // Logical Maximum (1)
- 0x75, 0x01, // Report Size (1)
- 0x95, 0x03, // Report Count (3)
- 0x81, 0x02, // Input (Data, Variable, Absolute) - Button states
- 0x75, 0x05, // Report Size (5)
- 0x95, 0x01, // Report Count (1)
- 0x81, 0x01, // Input (Constant) - Padding or Reserved bits
- 0x05, 0x01, // Usage Page (Generic Desktop)
- 0x09, 0x30, // Usage (X)
- 0x09, 0x31, // Usage (Y)
- 0x09, 0x38, // Usage (Wheel)
- 0x15, 0x81, // Logical Minimum (-127)
- 0x25, 0x7F, // Logical Maximum (127)
- 0x75, 0x08, // Report Size (8)
- 0x95, 0x03, // Report Count (3)
- 0x81, 0x06, // Input (Data, Variable, Relative) - X & Y coordinate
- 0xC0, // End Collection
- 0xC0, // End Collection
-
- 0x05, 0x01, // Usage Pg (Generic Desktop)
- 0x09, 0x06, // Usage (Keyboard)
- 0xA1, 0x01, // Collection: (Application)
- 0x85, 0x02, // Report Id (2)
- //
- 0x05, 0x07, // Usage Pg (Key Codes)
- 0x19, 0xE0, // Usage Min (224)
- 0x29, 0xE7, // Usage Max (231)
- 0x15, 0x00, // Log Min (0)
- 0x25, 0x01, // Log Max (1)
- //
- // Modifier byte
- 0x75, 0x01, // Report Size (1)
- 0x95, 0x08, // Report Count (8)
- 0x81, 0x02, // Input: (Data, Variable, Absolute)
- //
- // Reserved byte
- 0x95, 0x01, // Report Count (1)
- 0x75, 0x08, // Report Size (8)
- 0x81, 0x01, // Input: (Constant)
- //
- // LED report
- 0x95, 0x05, // Report Count (5)
- 0x75, 0x01, // Report Size (1)
- 0x05, 0x08, // Usage Pg (LEDs)
- 0x19, 0x01, // Usage Min (1)
- 0x29, 0x05, // Usage Max (5)
- 0x91, 0x02, // Output: (Data, Variable, Absolute)
- //
- // LED report padding
- 0x95, 0x01, // Report Count (1)
- 0x75, 0x03, // Report Size (3)
- 0x91, 0x01, // Output: (Constant)
- //
- // Key arrays (6 bytes)
- 0x95, 0x06, // Report Count (6)
- 0x75, 0x08, // Report Size (8)
- 0x15, 0x00, // Log Min (0)
- 0x25, 0x65, // Log Max (101)
- 0x05, 0x07, // Usage Pg (Key Codes)
- 0x19, 0x00, // Usage Min (0)
- 0x29, 0x65, // Usage Max (101)
- 0x81, 0x00, // Input: (Data, Array)
- //
- 0xC0, // End Collection
- //
- 0x05, 0x0C, // Usage Pg (Consumer Devices)
- 0x09, 0x01, // Usage (Consumer Control)
- 0xA1, 0x01, // Collection (Application)
- 0x85, 0x03, // Report Id (3)
- 0x09, 0x02, // Usage (Numeric Key Pad)
- 0xA1, 0x02, // Collection (Logical)
- 0x05, 0x09, // Usage Pg (Button)
- 0x19, 0x01, // Usage Min (Button 1)
- 0x29, 0x0A, // Usage Max (Button 10)
- 0x15, 0x01, // Logical Min (1)
- 0x25, 0x0A, // Logical Max (10)
- 0x75, 0x04, // Report Size (4)
- 0x95, 0x01, // Report Count (1)
- 0x81, 0x00, // Input (Data, Ary, Abs)
- 0xC0, // End Collection
- 0x05, 0x0C, // Usage Pg (Consumer Devices)
- 0x09, 0x86, // Usage (Channel)
- 0x15, 0xFF, // Logical Min (-1)
- 0x25, 0x01, // Logical Max (1)
- 0x75, 0x02, // Report Size (2)
- 0x95, 0x01, // Report Count (1)
- 0x81, 0x46, // Input (Data, Var, Rel, Null)
- 0x09, 0xE9, // Usage (Volume Up)
- 0x09, 0xEA, // Usage (Volume Down)
- 0x15, 0x00, // Logical Min (0)
- 0x75, 0x01, // Report Size (1)
- 0x95, 0x02, // Report Count (2)
- 0x81, 0x02, // Input (Data, Var, Abs)
- 0x09, 0xE2, // Usage (Mute)
- 0x09, 0x30, // Usage (Power)
- 0x09, 0x83, // Usage (Recall Last)
- 0x09, 0x81, // Usage (Assign Selection)
- 0x09, 0xB0, // Usage (Play)
- 0x09, 0xB1, // Usage (Pause)
- 0x09, 0xB2, // Usage (Record)
- 0x09, 0xB3, // Usage (Fast Forward)
- 0x09, 0xB4, // Usage (Rewind)
- 0x09, 0xB5, // Usage (Scan Next)
- 0x09, 0xB6, // Usage (Scan Prev)
- 0x09, 0xB7, // Usage (Stop)
- 0x15, 0x01, // Logical Min (1)
- 0x25, 0x0C, // Logical Max (12)
- 0x75, 0x04, // Report Size (4)
- 0x95, 0x01, // Report Count (1)
- 0x81, 0x00, // Input (Data, Ary, Abs)
- 0x09, 0x80, // Usage (Selection)
- 0xA1, 0x02, // Collection (Logical)
- 0x05, 0x09, // Usage Pg (Button)
- 0x19, 0x01, // Usage Min (Button 1)
- 0x29, 0x03, // Usage Max (Button 3)
- 0x15, 0x01, // Logical Min (1)
- 0x25, 0x03, // Logical Max (3)
- 0x75, 0x02, // Report Size (2)
- 0x81, 0x00, // Input (Data, Ary, Abs)
- 0xC0, // End Collection
- 0x81, 0x03, // Input (Const, Var, Abs)
- 0xC0 // End Collection
-};
-
-// HID report map length
-uint8_t hidReportMapLen = sizeof(hidReportMap);
-
-uint8_t hidProtocolMode = HID_PROTOCOL_MODE_REPORT;
-
-// HID report mapping table
-static hidRptMap_t hidRptMap[HID_NUM_REPORTS];
-
-
-esp_bt_uuid_t char_info_uuid = {LEN_UUID_16, {CHAR_HID_INFO_UUID}};
-esp_bt_uuid_t char_ctnl_pt_uuid = {LEN_UUID_16, {CHAR_HID_CTNL_PT_UUID}};
-esp_bt_uuid_t char_report_map_uuid = {LEN_UUID_16, {CHAR_REPORT_MAP_UUID}};
-esp_bt_uuid_t char_report_uuid = {LEN_UUID_16, {CHAR_REPORT_UUID}};
-esp_bt_uuid_t char_proto_mode_uuid = {LEN_UUID_16, {CHAR_PROTOCOL_MODE_UUID}};
-esp_bt_uuid_t char_kb_in_report_uuid = {LEN_UUID_16, {CHAR_BOOT_KB_IN_REPORT_UUID}};
-esp_bt_uuid_t char_kb_out_report_uuid = {LEN_UUID_16, {CHAR_BOOT_KB_OUT_REPORT_UUID}};
-esp_bt_uuid_t char_mouse_in_report_uuid = {LEN_UUID_16, {CHAR_BOOT_MOUSE_IN_REPORT_UUID}};
-
-
-
-/// Full HID device Database Description - Used to add attributes into the database
-const char_desc_t hids_char_db[HIDD_LE_CHAR_MAX] = {
- // HID Information Characteristic Value
- [HIDD_LE_INFO_CHAR] = {
- &char_info_uuid,
- GATT_PERM_READ,
- GATT_CHAR_PROP_BIT_READ
- },
-
- // HID Control Point Characteristic Value
- [HIDD_LE_CTNL_PT_CHAR] = {
- &char_ctnl_pt_uuid,
- GATT_PERM_WRITE,
- GATT_CHAR_PROP_BIT_WRITE_NR
- },
-
- // Report Map Characteristic Value
- [HIDD_LE_REPORT_MAP_CHAR] = {
- &char_report_map_uuid,
- GATT_PERM_READ,
- GATT_CHAR_PROP_BIT_READ
- },
- // Report Characteristic Value
- [HIDD_LE_REPORT_CHAR] = {
- &char_report_uuid,
- (GATT_PERM_READ | GATT_PERM_WRITE),
- (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE | GATT_CHAR_PROP_BIT_WRITE_NR)
- },
- // Protocol Mode Characteristic Declaration
- [HIDD_LE_PROTO_MODE_CHAR] = {
- &char_proto_mode_uuid,
- GATT_PERM_READ,
- GATT_CHAR_PROP_BIT_READ,
- },
-
- // Boot Keyboard Input Report Characteristic Value
- [HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = {
- &char_kb_in_report_uuid,
- GATT_PERM_READ,
- (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY),
-
- },
-
- // Boot Keyboard Output Report Characteristic Value
- [HIDD_LE_BOOT_KB_OUT_REPORT_CHAR] = {
- &char_kb_out_report_uuid,
- GATT_PERM_READ,
- (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE | GATT_CHAR_PROP_BIT_WRITE_NR)
- },
-
- // Boot Mouse Input Report Characteristic Value
- [HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR] = {
- &char_mouse_in_report_uuid,
- GATT_PERM_READ,
- (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY),
- },
-};
-
-static void hidd_add_characterisitc(const char_desc_t *char_desc);
-
-/*****************************************************************************
-** Constants
-*****************************************************************************/
-static void hidd_le_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data);
-
-/*******************************************************************************
-**
-** Function hidd_add_characterisitc
-**
-** Description the callback function after the hid device profile has been register to the BTA manager module
-**
-** Returns NULL
-**
-*******************************************************************************/
-static void hidd_add_characterisitc(const char_desc_t *char_desc)
-{
- uint16_t service_id;
- if (char_desc == NULL) {
- BTC_TRACE_ERROR("Invalid hid characteristic\n");
- return;
- }
- //check the hid device serivce has been register to the data base or not
- if (!hidd_le_env.enabled) {
- BTC_TRACE_ERROR("The hid device didn't register yet\n");
- return;
- }
- //get the service id from the env whitch has been register
- service_id = hidd_le_env.hidd_clcb.cur_srvc_id;
- if (char_desc->char_uuid != 0x00) {
- // start added the charact to the data base
- esp_ble_gatts_add_char (service_id,
- char_desc->char_uuid,
- char_desc->perm,
- char_desc->prop);
- }
-}
-
-
-/*******************************************************************************
-**
-** Function hidd_le_profile_cb
-**
-** Description the callback function after the hid device profile has been register to the BTA manager module
-**
-** Returns NULL
-**
-*******************************************************************************/
-static void hidd_le_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data)
-{
- esp_gatts_rsp_t rsp;
- esp_bt_uuid_t uuid = {LEN_UUID_16, {ATT_SVC_HID}};
- static uint8_t hid_char_idx;
- hidd_clcb_t *p_clcb = NULL;
- uint8_t app_id = 0xff;
-
- switch (event) {
- case ESP_GATTS_REG_EVT:
- //check the register of the hid device profile has been succeess or not
- if (p_data->reg_oper.status != ESP_GATT_OK) {
- BTC_TRACE_ERROR("hidd profile register failed\n");
- }
- hidd_le_env.hidd_inst.app_id = app_id;
- //save the gatt interface in the hid device ENV
- hidd_le_env.gatt_if = p_data->reg_oper.server_if;
- //set the env flag to enable
- hidd_le_env.enabled = true;
- //create the hid device service to the service data base.
- if (p_data->reg_oper.uuid.uu.uuid16 == ATT_SVC_HID) {
- hidd_le_create_service(true);
- }
- break;
- case ESP_GATTS_CREATE_EVT:
- if (p_data->create.uuid.uu.uuid16 == ATT_SVC_HID) {
- ///store the service id to the env
- hidd_le_env.hidd_clcb.cur_srvc_id = p_data->create.service_id;
- //start the button service after created
- esp_ble_gatts_start_srvc(p_data->create.service_id);
- hid_char_idx = HIDD_LE_INFO_CHAR;
- //added the info character to the data base.
- hidd_add_characterisitc(&hids_char_db[hid_char_idx]);
- hid_char_idx++;
- }
-
- break;
- case ESP_GATTS_ADD_INCL_SRVC_EVT:
-
- break;
- case ESP_GATTS_ADD_CHAR_EVT:
- //save the charateristic handle to the env
- hidd_le_env.hidd_inst.att_tbl[hid_char_idx - 1] = p_data->add_result.attr_id;
- BTC_TRACE_ERROR("hanlder = %x, p_data->add_result.char_uuid.uu.uuid16 = %x\n", p_data->add_result.attr_id,
- p_data->add_result.char_uuid.uu.uuid16);
- BTC_TRACE_ERROR("hid_char_idx=%x\n", hid_char_idx);
- if (hid_char_idx <= HIDD_LE_CHAR_MAX) { //added the characteristic until the index overflow
-
- if ((p_data->add_result.char_uuid.uu.uuid16 == CHAR_BOOT_KB_IN_REPORT_UUID) ||
- (p_data->add_result.char_uuid.uu.uuid16 == CHAR_BOOT_MOUSE_IN_REPORT_UUID)) {
- // add the gattc config descriptor to the notify charateristic
- //tBTA_GATT_PERM perm = (GATT_PERM_WRITE|GATT_PERM_WRITE);
- uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
- BTC_TRACE_ERROR("p_data->add_result.char_uuid.uu.uuid16 = %x\n",
- p_data->add_result.char_uuid.uu.uuid16);
- esp_ble_gatts_add_char_descr (hidd_le_env.hidd_clcb.cur_srvc_id,
- GATT_PERM_WRITE,
- &uuid);
-
-
- break;
- }
- hidd_add_characterisitc(&hids_char_db[hid_char_idx]);
- }
- hid_char_idx++;
- break;
- case ESP_GATTS_ADD_CHAR_DESCR_EVT:
- if (p_data->add_result.char_uuid.uu.uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) {
- uuid.uu.uuid16 = GATT_UUID_RPT_REF_DESCR;
- BTA_GATTS_AddCharDescriptor (hidd_le_env.hidd_clcb.cur_srvc_id,
- GATT_PERM_READ,
- &uuid);
- BTC_TRACE_ERROR("p_data->add_result.char_uuid.uu.uuid16 = %x\n",
- p_data->add_result.char_uuid.uu.uuid16);
- }
- if (p_data->add_result.char_uuid.uu.uuid16 == GATT_UUID_RPT_REF_DESCR) {
- if (hid_char_idx < HIDD_LE_CHAR_MAX) {
- hidd_add_characterisitc(&hids_char_db[hid_char_idx]);
- hid_char_idx++;
- }
- }
- break;
- case ESP_GATTS_READ_EVT: {
- BTC_TRACE_ERROR("Hidd profile BTA_GATTS_READ_EVT\n");
- UINT32 trans_id = p_data->req_data.trans_id;
- UINT16 conn_id = p_data->req_data.conn_id;
- UINT16 handle = p_data->req_data.p_data->read_req.handle;
- bool is_long = p_data->req_data.p_data->read_req.is_long;
- BTC_TRACE_ERROR("read request:event=0x%x,handle=0x%x,trans_id=0x%x,conn_id=0x%x\n",
- event, handle, trans_id, conn_id);
-
- hidd_read_attr_value(p_data->req_data.p_data, trans_id);
- }
- break;
- case ESP_GATTS_WRITE_EVT:
- esp_ble_gatts_send_rsp (p_data->req_data.conn_id, p_data->req_data.trans_id,
- p_data->req_data.status, NULL);
- break;
- case ESP_GATTS_CONNECT_EVT:
- p_clcb = &hidd_le_env.hidd_clcb;
-
- if (!p_clcb->in_use) {
- p_clcb->in_use = TRUE;
- p_clcb->conn_id = p_data->conn.conn_id;;
- BTC_TRACE_ERROR("hidd->conn_id = %x\n", p_data->conn.conn_id);
- p_clcb->connected = TRUE;
- memcpy(p_clcb->remote_bda, p_data->conn.remote_bda, BD_ADDR_LEN);
- }
- break;
- case ESP_GATTS_DISCONNECT_EVT:
- p_clcb = &hidd_le_env.hidd_clcb;
- //set the connection flag to true
- p_clcb->connected = false;
- p_clcb->in_use = TRUE;
- memset(p_clcb->remote_bda, 0, BD_ADDR_LEN);
- break;
- case ESP_GATTS_START_EVT:
- break;
- case ESP_GATTS_CONGEST_EVT:
- if (hidd_le_env.hidd_clcb.connected && (hidd_le_env.hidd_clcb.conn_id == p_data->conn.conn_id)) {
- //set the connection channal congested flag to true
- hidd_le_env.hidd_clcb.congest = p_data->congest.congested;
- }
- break;
- default:
- break;
- }
-}
-
-/*******************************************************************************
-**
-** Function hidd_le_create_service
-**
-** Description Create a Service for the hid device profile
-**
-** Parameters is_primary: this service is the primary service or not,true is the primary service
-** false is not the primary service
-** p_service_uuid: service UUID.
-**
-** Returns NULL
-**
-*******************************************************************************/
-void hidd_le_create_service(BOOLEAN is_primary)
-{
- esp_gatts_if_t server_if ;
- esp_bt_uuid_t uuid = {LEN_UUID_16, {ATT_SVC_HID}};
- //the number of the hid device attributes in the hid service.
- UINT16 num_handle = HIDD_LE_IDX_NB;
- UINT8 inst = 0x00;
- server_if = hidd_le_env.gatt_if;
- hidd_le_env.inst_id = inst;
- //start create the hid device service
- esp_ble_gatts_create_srvc (server_if, &uuid, inst, num_handle, is_primary);
-}
-
-
-/*****************************************************************************
-** Function hidd_read_attr_value
-**
-** Description it will be called when client sends a read request
-******************************************************************************/
-void hidd_read_attr_value(tGATTS_DATA *p_data, uint32_t trans_id)
-{
- hidd_inst_t *p_inst = &hidd_le_env.hidd_inst;
- uint8_t i;
- uint8_t status = ESP_GATT_OK;
- uint8_t app_id = hidd_le_env.hidd_inst.app_id;
-
- esp_gatt_status_t st = ESP_GATT_NOT_FOUND;
- uint16_t handle = p_data->read_req.handle;
- uint16_t conn_id = hidd_le_env.hidd_clcb.conn_id;
-
- if (handle == p_inst->att_tbl[HIDD_LE_INFO_CHAR]) {
- //read hid device info evt
- p_inst->pending_evt = HIDD_LE_READ_INFO_EVT;
-
- } else if (handle == p_inst->att_tbl[HIDD_LE_CTNL_PT_CHAR]) {
- //read hid device contol point evt
- p_inst->pending_evt = HIDD_LE_READ_CTNL_PT_EVT;
- } else if (handle == p_inst->att_tbl[HIDD_LE_REPORT_MAP_CHAR]) {
- //read hid device report map value evt
- p_inst->pending_evt = HIDD_LE_READ_REPORT_MAP_EVT;
- } else if (handle == p_inst->att_tbl[HIDD_LE_REPORT_CHAR]) {
- //read hid device report evt
- p_inst->pending_evt = HIDD_LE_READ_REPORT_EVT;
- } else if (handle == p_inst->att_tbl[HIDD_LE_PROTO_MODE_CHAR]) {
- //read hid device mode evt
- p_inst->pending_evt = HIDD_LE_READ_PROTO_MODE_EVT;
- } else if (handle == p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]) {
- //read hid boot keyboard in report evt
- p_inst->pending_evt = HIDD_LE_BOOT_KB_IN_REPORT_EVT;
- } else if (handle == p_inst->att_tbl[HIDD_LE_BOOT_KB_OUT_REPORT_CHAR]) {
- //read hid boot keyboard out report evt
- p_inst->pending_evt = HIDD_LE_BOOT_KB_OUT_REPORT_EVT;
- } else if (handle == p_inst->att_tbl[HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR]) {
- //read hid device boot mouse in report evt
- p_inst->pending_evt = HIDD_LE_BOOT_MOUSE_IN_REPORT_EVT;
- }
-
- //start build the rsp message
- hidd_rsp(trans_id, conn_id, app_id, status, p_inst->pending_evt, p_data);
-}
-
-/*******************************************************************************
-**
-** Function hidd_rsp
-**
-** Description Respond to a hid device service request
-**
-*******************************************************************************/
-void hidd_rsp (uint32_t trans_id, uint16_t conn_id, uint8_t app_id,
- esp_gatt_status_t status, uint8_t event, tGATTS_DATA *p_rsp)
-{
- hidd_inst_t *p_inst = &hidd_le_env.hidd_inst;
- tGATTS_RSP rsp;
- uint8_t *pp;
- BTC_TRACE_ERROR("conn_id = %x, trans_id = %x, event = %x\n",
- conn_id, trans_id, event);
-
- if (p_inst->app_id == app_id) {
- return ;
- }
-
- memset(&rsp, 0, sizeof(tGATTS_RSP));
-
- if (p_inst->pending_evt == event) {
- switch (event) {
- case HIDD_LE_READ_INFO_EVT:
- BTC_TRACE_ERROR(" p_inst->att_tbl[HIDD_LE_INFO_CHAR] = %x\n",
- p_inst->att_tbl[HIDD_LE_INFO_CHAR]);
- rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_INFO_CHAR];
- rsp.attr_value.len = HID_INFORMATION_LEN;
- //copy the infomation value to the att value to sent to the peer device
- memcpy(rsp.attr_value.value, hidInfo, HID_INFORMATION_LEN);
- //start send the rsp to the peer device
- esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
- break;
-
- case HIDD_LE_READ_CTNL_PT_EVT:
- BTC_TRACE_ERROR(" p_inst->att_tbl[HIDD_LE_CTNL_PT_CHAR] = %x\n",
- p_inst->att_tbl[HIDD_LE_CTNL_PT_CHAR]);
- rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_CTNL_PT_CHAR];
- rsp.attr_value.len = 0;
- //start send the rsp to the peer device
- esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
- break;
-
- case HIDD_LE_READ_REPORT_MAP_EVT:
- BTC_TRACE_ERROR("p_inst->att_tbl[HIDD_LE_REPORT_MAP_CHAR] = %x\n",
- p_inst->att_tbl[HIDD_LE_REPORT_MAP_CHAR]);
- rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_REPORT_MAP_CHAR];
- rsp.attr_value.len = hidReportMapLen;
- //copy the infomation value to the att value to sent to the peer device
- memcpy(rsp.attr_value.value, hidReportMap, hidReportMapLen);
- //start send the rsp to the peer device
- esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
- break;
- case HIDD_LE_READ_REPORT_EVT:
- BTC_TRACE_ERROR("p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = %x\n",
- p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]);
- rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR];
- rsp.attr_value.len = 0;
-
- esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
- break;
- case HIDD_LE_READ_PROTO_MODE_EVT:
- BTC_TRACE_ERROR("p_inst->att_tbl[HIDD_LE_PROTO_MODE_CHAR] = %x\n",
- p_inst->att_tbl[HIDD_LE_PROTO_MODE_CHAR]);
- rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_PROTO_MODE_CHAR];
- rsp.attr_value.len = 1;
- pp = rsp.attr_value.value;
- //copy the infomation value to the att value to sent to the peer device
- memcpy(rsp.attr_value.value, &hidProtocolMode, rsp.attr_value.len);
- esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
- break;
- case HIDD_LE_BOOT_KB_IN_REPORT_EVT:
- BTC_TRACE_ERROR("p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = %x\n",
- p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]);
- rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR];
- rsp.attr_value.len = 0;
-
- esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
- break;
- case HIDD_LE_BOOT_KB_OUT_REPORT_EVT:
- BTC_TRACE_ERROR("p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = %x\n",
- p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]);
- rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR];
- rsp.attr_value.len = 0;
-
- esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
- break;
- case HIDD_LE_BOOT_MOUSE_IN_REPORT_EVT:
- BTC_TRACE_ERROR("p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR] = %x\n",
- p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR]);
- rsp.attr_value.handle = p_inst->att_tbl[HIDD_LE_BOOT_KB_IN_REPORT_CHAR];
- rsp.attr_value.len = 0;
-
- esp_ble_gatts_send_rsp(conn_id, trans_id, status, &rsp);
- break;
- default:
- break;
- }
- // p_inst->pending_clcb_idx = 0;
- p_inst->pending_evt = 0;
- p_inst->pending_hal = 0;
- }
- return;
-}
-
-
-/*******************************************************************************
-**
-** Function hidd_le_init
-**
-** Description Initializa the GATT Service for button profiles.
-** Returns NULL
-*******************************************************************************/
-esp_gatt_status_t hidd_le_init (void)
-{
- tBT_UUID app_uuid = {LEN_UUID_16, {ATT_SVC_HID}};
-
- if (hidd_le_env.enabled) {
- BTC_TRACE_ERROR("hid device svc already initaliezd\n");
- return ESP_GATT_ERROR;
- } else {
- memset(&hidd_le_env, 0, sizeof(hidd_le_env_t));
- }
-
-
- /*
- register the hid deivce profile to the BTA_GATTS module*/
- esp_ble_gatts_app_register(&app_uuid, hidd_le_profile_cb);
-
- hidd_le_env.enabled = TRUE;
-
- return ESP_GATT_OK;
-}
-
-
-#endif ///HIDD_LE_PROFILE_CFG
-
-
diff --git a/components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h
index 9ee03d4117..c9e0f5645a 100644
--- a/components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h
+++ b/components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h
@@ -166,5 +166,7 @@ void btc_gap_ble_cb_deep_free(btc_msg_t *msg);
void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_gap_callback_init(void);
void btc_gap_ble_deinit(void);
+void btc_adv_list_init(void);
+void btc_adv_list_deinit(void);
#endif /* __BTC_GAP_BLE_H__ */
diff --git a/components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h b/components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h
index 41674956cb..166b3e248e 100644
--- a/components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h
+++ b/components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h
@@ -26,8 +26,11 @@ typedef enum {
BTC_GAP_BT_SEARCH_DEVICES_EVT = 0,
BTC_GAP_BT_SEARCH_SERVICES_EVT,
BTC_GAP_BT_SEARCH_SERVICE_RECORD_EVT,
- BTC_GAP_BT_READ_RSSI_DELTA_EVT,
BTC_GAP_BT_AUTH_CMPL_EVT,
+ BTC_GAP_BT_CFM_REQ_EVT,
+ BTC_GAP_BT_KEY_NOTIF_EVT,
+ BTC_GAP_BT_KEY_REQ_EVT,
+ BTC_GAP_BT_READ_RSSI_DELTA_EVT,
}btc_gap_bt_evt_t;
typedef enum {
@@ -39,6 +42,9 @@ typedef enum {
BTC_GAP_BT_ACT_SET_COD,
BTC_GAP_BT_ACT_READ_RSSI_DELTA,
BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE,
+ BTC_GAP_BT_ACT_SET_SECURITY_PARAM,
+ BTC_GAP_BT_ACT_PASSKEY_REPLY,
+ BTC_GAP_BT_ACT_CONFIRM_REPLY,
} btc_gap_bt_act_t;
/* btc_bt_gap_args_t */
@@ -79,11 +85,31 @@ typedef union {
struct rm_bond_device_args {
bt_bdaddr_t bda;
} rm_bond_device;
+
+ // BTC_GAP_BT_ACT_SET_SECURITY_PARAM
+ struct set_sec_param_args {
+ esp_bt_sp_param_t param_type;
+ uint8_t len;
+ uint8_t *value;
+ } set_security_param;
+
+ // BTC_GAP_BT_ACT_PASSKEY_REPLY
+ struct passkey_reply_args {
+ bt_bdaddr_t bda;
+ bool accept;
+ uint32_t passkey;
+ } passkey_reply;
+
+ // BTC_GAP_BT_ACT_CONFIRM_REPLY
+ struct confirm_reply_args {
+ bt_bdaddr_t bda;
+ bool accept;
+ } confirm_reply;
} btc_gap_bt_args_t;
void btc_gap_bt_call_handler(btc_msg_t *msg);
void btc_gap_bt_cb_handler(btc_msg_t *msg);
-
+void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_gap_bt_busy_level_updated(uint8_t bl_flags);
esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod);
diff --git a/components/bt/bluedroid/btc/profile/std/include/hid_le_prf.h b/components/bt/bluedroid/btc/profile/std/include/hid_le_prf.h
deleted file mode 100644
index 3b567d0c2d..0000000000
--- a/components/bt/bluedroid/btc/profile/std/include/hid_le_prf.h
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright 2015-2016 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.
-
-#include "prf_defs.h"
-
-#if (HIDD_LE_PROFILE_CFG)
-#include "bta_gatts_int.h"
-#include "stack/bt_types.h"
-#include "bta/bta_api.h"
-#include "stack/gatt_api.h"
-#include "bt_app_api.h"
-
-/// Maximal number of HIDS that can be added in the DB
-#ifndef USE_ONE_HIDS_INSTANCE
-#define HIDD_LE_NB_HIDS_INST_MAX (2)
-#else
-#define HIDD_LE_NB_HIDS_INST_MAX (1)
-#endif
-
-// Number of HID reports defined in the service
-#define HID_NUM_REPORTS 9
-
-
-#define ATT_SVC_HID 0x1812
-
-/// Maximal number of Report Char. that can be added in the DB for one HIDS - Up to 11
-#define HIDD_LE_NB_REPORT_INST_MAX (5)
-
-/// Maximal length of Report Char. Value
-#define HIDD_LE_REPORT_MAX_LEN (45)
-/// Maximal length of Report Map Char. Value
-#define HIDD_LE_REPORT_MAP_MAX_LEN (512)
-
-/// Length of Boot Report Char. Value Maximal Length
-#define HIDD_LE_BOOT_REPORT_MAX_LEN (8)
-
-/// Boot KB Input Report Notification Configuration Bit Mask
-#define HIDD_LE_BOOT_KB_IN_NTF_CFG_MASK (0x40)
-/// Boot KB Input Report Notification Configuration Bit Mask
-#define HIDD_LE_BOOT_MOUSE_IN_NTF_CFG_MASK (0x80)
-/// Boot Report Notification Configuration Bit Mask
-#define HIDD_LE_REPORT_NTF_CFG_MASK (0x20)
-
-
-/* HID information flags */
-#define HID_FLAGS_REMOTE_WAKE 0x01 // RemoteWake
-#define HID_FLAGS_NORMALLY_CONNECTABLE 0x02 // NormallyConnectable
-
-/* Control point commands */
-#define HID_CMD_SUSPEND 0x00 // Suspend
-#define HID_CMD_EXIT_SUSPEND 0x01 // Exit Suspend
-
-/* HID protocol mode values */
-#define HID_PROTOCOL_MODE_BOOT 0x00 // Boot Protocol Mode
-#define HID_PROTOCOL_MODE_REPORT 0x01 // Report Protocol Mode
-
-/* Attribute value lengths */
-#define HID_PROTOCOL_MODE_LEN 1 // HID Protocol Mode
-#define HID_INFORMATION_LEN 4 // HID Information
-#define HID_REPORT_REF_LEN 2 // HID Report Reference Descriptor
-#define HID_EXT_REPORT_REF_LEN 2 // External Report Reference Descriptor
-
-// HID feature flags
-#define HID_KBD_FLAGS HID_FLAGS_REMOTE_WAKE
-
-
-/// HID Service Attributes Indexes
-enum {
- HIDD_LE_IDX_SVC,
-
- // Included Service
- HIDD_LE_IDX_INCL_SVC,
-
- // HID Information
- HIDD_LE_IDX_HID_INFO_CHAR,
- HIDD_LE_IDX_HID_INFO_VAL,
-
- // HID Control Point
- HIDD_LE_IDX_HID_CTNL_PT_CHAR,
- HIDD_LE_IDX_HID_CTNL_PT_VAL,
-
- // Report Map
- HIDD_LE_IDX_REPORT_MAP_CHAR,
- HIDD_LE_IDX_REPORT_MAP_VAL,
- HIDD_LE_IDX_REPORT_MAP_EXT_REP_REF,
-
- // Protocol Mode
- HIDD_LE_IDX_PROTO_MODE_CHAR,
- HIDD_LE_IDX_PROTO_MODE_VAL,
-
- // Boot Keyboard Input Report
- HIDD_LE_IDX_BOOT_KB_IN_REPORT_CHAR,
- HIDD_LE_IDX_BOOT_KB_IN_REPORT_VAL,
- HIDD_LE_IDX_BOOT_KB_IN_REPORT_NTF_CFG,
-
- // Boot Keyboard Output Report
- HIDD_LE_IDX_BOOT_KB_OUT_REPORT_CHAR,
- HIDD_LE_IDX_BOOT_KB_OUT_REPORT_VAL,
-
- // Boot Mouse Input Report
- HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_CHAR,
- HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_VAL,
- HIDD_LE_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG,
-
- // Report
- HIDD_LE_IDX_REPORT_CHAR,
- HIDD_LE_IDX_REPORT_VAL,
- HIDD_LE_IDX_REPORT_REP_REF,
- HIDD_LE_IDX_REPORT_NTF_CFG,
-
- HIDD_LE_IDX_NB,
-};
-
-
-/// Attribute Table Indexes
-enum {
- HIDD_LE_INFO_CHAR,
- HIDD_LE_CTNL_PT_CHAR,
- HIDD_LE_REPORT_MAP_CHAR,
- HIDD_LE_REPORT_CHAR,
- HIDD_LE_PROTO_MODE_CHAR,
- HIDD_LE_BOOT_KB_IN_REPORT_CHAR,
- HIDD_LE_BOOT_KB_OUT_REPORT_CHAR,
- HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR,
- HIDD_LE_CHAR_MAX //= HIDD_LE_REPORT_CHAR + HIDD_LE_NB_REPORT_INST_MAX,
-};
-
-///att read event table Indexs
-enum {
- HIDD_LE_READ_INFO_EVT,
- HIDD_LE_READ_CTNL_PT_EVT,
- HIDD_LE_READ_REPORT_MAP_EVT,
- HIDD_LE_READ_REPORT_EVT,
- HIDD_LE_READ_PROTO_MODE_EVT,
- HIDD_LE_BOOT_KB_IN_REPORT_EVT,
- HIDD_LE_BOOT_KB_OUT_REPORT_EVT,
- HIDD_LE_BOOT_MOUSE_IN_REPORT_EVT,
-
- HID_LE_EVT_MAX
-};
-
-/// Client Characteristic Configuration Codes
-enum {
- HIDD_LE_DESC_MASK = 0x10,
-
- HIDD_LE_BOOT_KB_IN_REPORT_CFG = HIDD_LE_BOOT_KB_IN_REPORT_CHAR | HIDD_LE_DESC_MASK,
- HIDD_LE_BOOT_MOUSE_IN_REPORT_CFG = HIDD_LE_BOOT_MOUSE_IN_REPORT_CHAR | HIDD_LE_DESC_MASK,
- HIDD_LE_REPORT_CFG = HIDD_LE_REPORT_CHAR | HIDD_LE_DESC_MASK,
-};
-
-/// Features Flag Values
-enum {
- HIDD_LE_CFG_KEYBOARD = 0x01,
- HIDD_LE_CFG_MOUSE = 0x02,
- HIDD_LE_CFG_PROTO_MODE = 0x04,
- HIDD_LE_CFG_MAP_EXT_REF = 0x08,
- HIDD_LE_CFG_BOOT_KB_WR = 0x10,
- HIDD_LE_CFG_BOOT_MOUSE_WR = 0x20,
-};
-
-/// Report Char. Configuration Flag Values
-enum {
- HIDD_LE_CFG_REPORT_IN = 0x01,
- HIDD_LE_CFG_REPORT_OUT = 0x02,
- //HOGPD_CFG_REPORT_FEAT can be used as a mask to check Report type
- HIDD_LE_CFG_REPORT_FEAT = 0x03,
- HIDD_LE_CFG_REPORT_WR = 0x10,
-};
-
-/// Pointer to the connection clean-up function
-#define HIDD_LE_CLEANUP_FNCT (NULL)
-
-/*
- * TYPE DEFINITIONS
- ****************************************************************************************
- */
-
-/// HIDD Features structure
-typedef struct {
- /// Service Features
- uint8_t svc_features;
- /// Number of Report Char. instances to add in the database
- uint8_t report_nb;
- /// Report Char. Configuration
- uint8_t report_char_cfg[HIDD_LE_NB_REPORT_INST_MAX];
-} hidd_feature_t;
-
-
-typedef struct {
- BOOLEAN in_use;
- BOOLEAN congest;
- uint16_t conn_id;
- BOOLEAN connected;
- BD_ADDR remote_bda;
- uint32_t trans_id;
- uint8_t cur_srvc_id;
-
-} hidd_clcb_t;
-
-// HID report mapping table
-typedef struct {
- uint16_t handle; // Handle of report characteristic
- uint16_t cccdHandle; // Handle of CCCD for report characteristic
- uint8_t id; // Report ID
- uint8_t type; // Report type
- uint8_t mode; // Protocol mode (report or boot)
-} hidRptMap_t;
-
-
-typedef struct {
- /// hidd profile id
- uint8_t app_id;
- /// Notified handle
- uint16_t ntf_handle;
- ///Attribute handle Table
- uint16_t att_tbl[HIDD_LE_CHAR_MAX];
- /// Supported Features
- hidd_feature_t hidd_feature[HIDD_LE_NB_HIDS_INST_MAX];
- /// Current Protocol Mode
- uint8_t proto_mode[HIDD_LE_NB_HIDS_INST_MAX];
- /// Number of HIDS added in the database
- uint8_t hids_nb;
- uint8_t pending_evt;
- uint16_t pending_hal;
-} hidd_inst_t;
-
-
-/* service engine control block */
-typedef struct {
- hidd_clcb_t hidd_clcb; /* connection link*/
- esp_gatt_if_t gatt_if;
- BOOLEAN enabled;
- BOOLEAN is_primery;
- hidd_inst_t hidd_inst;
- uint8_t inst_id;
-} hidd_le_env_t;
-
-extern hidd_le_env_t hidd_le_env;
-
-
-void hidd_le_create_service(BOOLEAN is_primary);
-
-void hidd_rsp (uint32_t trans_id, uint16_t conn_id, uint8_t app_id,
- esp_gatt_status_t status, uint8_t event, tGATTS_DATA *p_rsp);
-
-void hidd_read_attr_value(tGATTS_DATA *p_data, uint32_t trans_id);
-
-
-tGATT_STATUS hidd_le_init (void);
-
-
-#endif ///HIDD_LE_PROFILE_CFG
-
-
diff --git a/components/bt/bluedroid/common/include/common/bt_defs.h b/components/bt/bluedroid/common/include/common/bt_defs.h
index 51ba9a9de1..77719bc847 100644
--- a/components/bt/bluedroid/common/include/common/bt_defs.h
+++ b/components/bt/bluedroid/common/include/common/bt_defs.h
@@ -26,9 +26,6 @@
#define UNUSED(x) (void)(x)
-#ifndef SIZE_MAX
-#define SIZE_MAX 254
-#endif
/*Timer Related Defination*/
//by Snake.T
diff --git a/components/bt/bluedroid/common/include/common/bt_target.h b/components/bt/bluedroid/common/include/common/bt_target.h
index fc12bde071..7782526d02 100644
--- a/components/bt/bluedroid/common/include/common/bt_target.h
+++ b/components/bt/bluedroid/common/include/common/bt_target.h
@@ -94,6 +94,10 @@
#define CLASSIC_BT_INCLUDED FALSE
#endif /* CLASSIC_BT_INCLUDED */
+#ifndef CONFIG_GATTC_CACHE_NVS_FLASH
+#define CONFIG_GATTC_CACHE_NVS_FLASH FALSE
+#endif /* CONFIG_GATTC_CACHE_NVS_FLASH */
+
/******************************************************************************
**
** BLE features
@@ -111,13 +115,25 @@
#define GATTC_INCLUDED FALSE
#endif /* CONFIG_GATTC_ENABLE */
+#if (CONFIG_GATTC_ENABLE && CONFIG_GATTC_CACHE_NVS_FLASH)
+#define GATTC_CACHE_NVS TRUE
+#else
+#define GATTC_CACHE_NVS FALSE
+#endif /* CONFIG_GATTC_CACHE_NVS_FLASH */
+
#if (CONFIG_SMP_ENABLE)
#define SMP_INCLUDED TRUE
#define BLE_PRIVACY_SPT TRUE
#else
#define SMP_INCLUDED FALSE
#define BLE_PRIVACY_SPT FALSE
-#endif /* CONFIG_GATTC_ENABLE */
+#endif /* CONFIG_SMP_ENABLE */
+
+#if (CONFIG_BT_SSP_ENABLE)
+#define BT_SSP_INCLUDED TRUE
+#else
+#define BT_SSP_INCLUDED FALSE
+#endif /* CONFIG_BT_SSP_ENABLE */
#if (CONFIG_BT_ACL_CONNECTIONS)
#define MAX_ACL_CONNECTIONS CONFIG_BT_ACL_CONNECTIONS
@@ -297,6 +313,16 @@
#define BTA_AV_CO_CP_SCMS_T FALSE//FALSE
#endif
+#ifndef QUEUE_CONGEST_SIZE
+#define QUEUE_CONGEST_SIZE 40
+#endif
+
+#ifndef CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK
+#define SCAN_QUEUE_CONGEST_CHECK FALSE
+#else
+#define SCAN_QUEUE_CONGEST_CHECK CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK
+#endif
+
/* This feature is used to eanble interleaved scan*/
#ifndef BTA_HOST_INTERLEAVE_SEARCH
#define BTA_HOST_INTERLEAVE_SEARCH FALSE//FALSE
@@ -571,7 +597,7 @@
#define BTM_DEFAULT_DISC_INTERVAL 0x0800
#endif
-/*
+/*
* {SERVICE_CLASS, MAJOR_CLASS, MINOR_CLASS}
*
* SERVICE_CLASS:0x5A (Bit17 -Networking,Bit19 - Capturing,Bit20 -Object Transfer,Bit22 -Telephony)
@@ -744,6 +770,14 @@
#define BTM_BLE_CONFORMANCE_TESTING FALSE
#endif
+/******************************************************************************
+**
+** CONTROLLER TO HOST FLOW CONTROL
+**
+******************************************************************************/
+
+#define C2H_FLOW_CONTROL_INCLUDED TRUE
+
/******************************************************************************
**
** L2CAP
@@ -1127,6 +1161,20 @@
#define SMP_LINK_TOUT_MIN 2
#endif
#endif
+
+/******************************************************************************
+**
+** BT_SSP
+**
+******************************************************************************/
+#ifndef BT_SSP_INCLUDED
+#define BT_SSP_INCLUDED FALSE
+#endif
+
+#if BT_SSP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == FALSE
+#error "Can't have SSP without CLASSIC BT"
+#endif
+
/******************************************************************************
**
** SDP
diff --git a/components/bt/bluedroid/common/include/common/bte_appl.h b/components/bt/bluedroid/common/include/common/bte_appl.h
index 4850250b8a..47a0184b7f 100644
--- a/components/bt/bluedroid/common/include/common/bte_appl.h
+++ b/components/bt/bluedroid/common/include/common/bte_appl.h
@@ -32,6 +32,18 @@ typedef struct {
UINT8 ble_resp_key;
UINT8 ble_max_key_size;
#endif
+
} tBTE_APPL_CFG;
extern tBTE_APPL_CFG bte_appl_cfg;
+
+
+typedef struct {
+#if ((CLASSIC_BT_INCLUDED == TRUE) && (BT_SSP_INCLUDED == TRUE))
+ UINT8 bt_auth_req;
+ UINT8 bt_io_cap;
+ UINT8 *bt_oob_auth_data;
+#endif
+} tBTE_BT_APPL_CFG;
+
+extern tBTE_BT_APPL_CFG bte_bt_appl_cfg;
\ No newline at end of file
diff --git a/components/bt/bluedroid/device/controller.c b/components/bt/bluedroid/device/controller.c
index 06b8a52c7c..f0963b4695 100644
--- a/components/bt/bluedroid/device/controller.c
+++ b/components/bt/bluedroid/device/controller.c
@@ -95,6 +95,12 @@ static void start_up(void)
response, &acl_data_size_classic, &acl_buffer_count_classic,
&sco_data_size, &sco_buffer_count);
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+ // Enable controller to host flow control
+ response = AWAIT_COMMAND(packet_factory->make_set_c2h_flow_control(HCI_HOST_FLOW_CTRL_ACL_ON));
+ packet_parser->parse_generic_command_complete(response);
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
// Tell the controller about our buffer sizes and buffer counts next
// TODO(zachoverflow): factor this out. eww l2cap contamination. And why just a hardcoded 10?
response = AWAIT_COMMAND(
@@ -252,6 +258,9 @@ static void start_up(void)
#if (BTM_SCO_HCI_INCLUDED == TRUE)
response = AWAIT_COMMAND(packet_factory->make_write_sync_flow_control_enable(1));
packet_parser->parse_generic_command_complete(response);
+
+ response = AWAIT_COMMAND(packet_factory->make_write_default_erroneous_data_report(1));
+ packet_parser->parse_generic_command_complete(response);
#endif
readable = true;
// return future_new_immediate(FUTURE_SUCCESS);
diff --git a/components/bt/bluedroid/hci/hci_hal_h4.c b/components/bt/bluedroid/hci/hci_hal_h4.c
index 8b87a6faa0..e910aa7b73 100644
--- a/components/bt/bluedroid/hci/hci_hal_h4.c
+++ b/components/bt/bluedroid/hci/hci_hal_h4.c
@@ -27,10 +27,16 @@
#include "osi/thread.h"
#include "esp_bt.h"
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+#include "l2c_int.h"
+#include "stack/hcimsgs.h"
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
#define HCI_HAL_SERIAL_BUFFER_SIZE 1026
#define HCI_BLE_EVENT 0x3e
#define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2)
#define PACKET_TYPE_TO_INDEX(type) ((type) - 1)
+extern bool BTU_check_queue_is_congest(void);
static const uint8_t preamble_sizes[] = {
@@ -92,6 +98,7 @@ static void hci_hal_env_init(
static void hci_hal_env_deinit(void)
{
fixed_queue_free(hci_hal_env.rx_q, hci_hal_env.allocator->free);
+ hci_hal_env.rx_q = NULL;
}
static bool hal_open(const hci_hal_callbacks_t *upper_callbacks)
@@ -99,7 +106,7 @@ static bool hal_open(const hci_hal_callbacks_t *upper_callbacks)
assert(upper_callbacks != NULL);
callbacks = upper_callbacks;
- hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX);
+ hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, QUEUE_SIZE_MAX);
xHciH4Queue = xQueueCreate(HCI_H4_QUEUE_LEN, sizeof(BtTaskEvt_t));
xTaskCreatePinnedToCore(hci_hal_h4_rx_handler, HCI_H4_TASK_NAME, HCI_H4_TASK_STACK_SIZE, NULL, HCI_H4_TASK_PRIO, &xHciH4TaskHandle, HCI_H4_TASK_PINNED_TO_CORE);
@@ -165,6 +172,7 @@ static void hci_hal_h4_rx_handler(void *arg)
if (pdTRUE == xQueueReceive(xHciH4Queue, &e, (portTickType)portMAX_DELAY)) {
if (e.sig == SIG_HCI_HAL_RECV_PACKET) {
fixed_queue_process(hci_hal_env.rx_q);
+
}
}
}
@@ -178,13 +186,51 @@ task_post_status_t hci_hal_h4_task_post(task_post_t timeout)
evt.par = 0;
if (xQueueSend(xHciH4Queue, &evt, timeout) != pdTRUE) {
- HCI_TRACE_ERROR("xHciH4Queue failed\n");
return TASK_POST_SUCCESS;
}
return TASK_POST_FAIL;
}
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+static void hci_packet_complete(BT_HDR *packet){
+ uint8_t type, num_handle;
+ uint16_t handle;
+ uint16_t handles[MAX_L2CAP_LINKS + 4];
+ uint16_t num_packets[MAX_L2CAP_LINKS + 4];
+ uint8_t *stream = packet->data + packet->offset;
+ tL2C_LCB *p_lcb = NULL;
+
+ STREAM_TO_UINT8(type, stream);
+ if (type == DATA_TYPE_ACL/* || type == DATA_TYPE_SCO*/) {
+ STREAM_TO_UINT16(handle, stream);
+ handle = handle & HCI_DATA_HANDLE_MASK;
+ p_lcb = l2cu_find_lcb_by_handle(handle);
+ if (p_lcb) {
+ p_lcb->completed_packets++;
+ }
+ if (esp_vhci_host_check_send_available()){
+ num_handle = l2cu_find_completed_packets(handles, num_packets);
+ if (num_handle > 0){
+ btsnd_hcic_host_num_xmitted_pkts (num_handle, handles, num_packets);
+ }
+ } else {
+ //Send HCI_Host_Number_of_Completed_Packets next time.
+ }
+
+ }
+}
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
+bool host_recv_adv_packet(BT_HDR *packet)
+{
+ assert(packet);
+ if(packet->data[0] == DATA_TYPE_EVENT && packet->data[1] == HCI_BLE_EVENT && packet->data[3] == HCI_BLE_ADV_PKT_RPT_EVT) {
+ return true;
+ }
+ return false;
+}
+
static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
{
uint8_t type, hdr_size;
@@ -194,6 +240,11 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
if (!packet) {
return;
}
+
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+ hci_packet_complete(packet);
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
STREAM_TO_UINT8(type, stream);
packet->offset++;
packet->len--;
@@ -233,6 +284,13 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
hci_hal_env.allocator->free(packet);
return;
}
+#if SCAN_QUEUE_CONGEST_CHECK
+ if(BTU_check_queue_is_congest() && host_recv_adv_packet(packet)) {
+ HCI_TRACE_ERROR("BtuQueue is congested");
+ hci_hal_env.allocator->free(packet);
+ return;
+ }
+#endif
packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
callbacks->packet_ready(packet);
@@ -260,6 +318,10 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
BT_HDR *pkt;
size_t pkt_size;
+ if (hci_hal_env.rx_q == NULL) {
+ return 0;
+ }
+
pkt_size = BT_HDR_SIZE + len;
pkt = (BT_HDR *)hci_hal_env.allocator->alloc(pkt_size);
if (!pkt) {
@@ -271,7 +333,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
pkt->layer_specific = 0;
memcpy(pkt->data, data, len);
fixed_queue_enqueue(hci_hal_env.rx_q, pkt);
- hci_hal_h4_task_post(TASK_POST_BLOCKING);
+ hci_hal_h4_task_post(100 / portTICK_PERIOD_MS);
BTTRC_DUMP_BUFFER("Recv Pkt", pkt->data, len);
diff --git a/components/bt/bluedroid/hci/hci_layer.c b/components/bt/bluedroid/hci/hci_layer.c
index 59b08c4810..b2120593ab 100644
--- a/components/bt/bluedroid/hci/hci_layer.c
+++ b/components/bt/bluedroid/hci/hci_layer.c
@@ -158,7 +158,7 @@ static int hci_layer_init_env(void)
// as per the Bluetooth spec, Volume 2, Part E, 4.4 (Command Flow Control)
// This value can change when you get a command complete or command status event.
hci_host_env.command_credits = 1;
- hci_host_env.command_queue = fixed_queue_new(SIZE_MAX);
+ hci_host_env.command_queue = fixed_queue_new(QUEUE_SIZE_MAX);
if (hci_host_env.command_queue) {
fixed_queue_register_dequeue(hci_host_env.command_queue, event_command_ready);
} else {
@@ -166,7 +166,7 @@ static int hci_layer_init_env(void)
return -1;
}
- hci_host_env.packet_queue = fixed_queue_new(SIZE_MAX);
+ hci_host_env.packet_queue = fixed_queue_new(QUEUE_SIZE_MAX);
if (hci_host_env.packet_queue) {
fixed_queue_register_dequeue(hci_host_env.packet_queue, event_packet_ready);
} else {
@@ -274,6 +274,7 @@ static void transmit_command(
fixed_queue_enqueue(hci_host_env.command_queue, wait_entry);
hci_host_task_post(TASK_POST_BLOCKING);
+
}
static future_t *transmit_command_futured(BT_HDR *command)
@@ -317,8 +318,14 @@ static void event_command_ready(fixed_queue_t *queue)
command_waiting_response_t *cmd_wait_q = &hci_host_env.cmd_waiting_q;
wait_entry = fixed_queue_dequeue(queue);
- hci_host_env.command_credits--;
+ if(wait_entry->opcode == HCI_HOST_NUM_PACKETS_DONE){
+ packet_fragmenter->fragment_and_dispatch(wait_entry->command);
+ buffer_allocator->free(wait_entry->command);
+ osi_free(wait_entry);
+ return;
+ }
+ hci_host_env.command_credits--;
// Move it to the list of commands awaiting response
osi_mutex_lock(&cmd_wait_q->commands_pending_response_lock, OSI_MUTEX_MAX_TIMEOUT);
list_append(cmd_wait_q->commands_pending_response, wait_entry);
@@ -435,7 +442,6 @@ static bool filter_incoming_event(BT_HDR *packet)
if (event_code == HCI_COMMAND_COMPLETE_EVT) {
STREAM_TO_UINT8(hci_host_env.command_credits, stream);
STREAM_TO_UINT16(opcode, stream);
-
wait_entry = get_waiting_command(opcode);
if (!wait_entry) {
HCI_TRACE_WARNING("%s command complete event with no matching command. opcode: 0x%x.", __func__, opcode);
diff --git a/components/bt/bluedroid/hci/hci_packet_factory.c b/components/bt/bluedroid/hci/hci_packet_factory.c
index 2c88570e3d..45f3f687fc 100644
--- a/components/bt/bluedroid/hci/hci_packet_factory.c
+++ b/components/bt/bluedroid/hci/hci_packet_factory.c
@@ -45,6 +45,16 @@ static BT_HDR *make_read_buffer_size(void)
return make_command_no_params(HCI_READ_BUFFER_SIZE);
}
+static BT_HDR *make_set_c2h_flow_control(uint8_t enable)
+{
+ uint8_t *stream;
+ const uint8_t parameter_size = 1;
+ BT_HDR *packet = make_command(HCI_SET_HC_TO_HOST_FLOW_CTRL, parameter_size, &stream);
+
+ UINT8_TO_STREAM(stream, enable);
+ return packet;
+}
+
static BT_HDR *make_host_buffer_size(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count)
{
uint8_t *stream;
@@ -184,6 +194,16 @@ static BT_HDR *make_write_sync_flow_control_enable(uint8_t enable)
UINT8_TO_STREAM(stream, enable);
return packet;
}
+
+static BT_HDR *make_write_default_erroneous_data_report(uint8_t enable)
+{
+ uint8_t *stream;
+ const uint8_t parameter_size = 1;
+ BT_HDR *packet = make_command(HCI_WRITE_ERRONEOUS_DATA_RPT, parameter_size, &stream);
+
+ UINT8_TO_STREAM(stream, enable);
+ return packet;
+}
// Internal functions
static BT_HDR *make_command_no_params(uint16_t opcode)
@@ -220,6 +240,7 @@ static BT_HDR *make_packet(size_t data_size)
static const hci_packet_factory_t interface = {
make_reset,
make_read_buffer_size,
+ make_set_c2h_flow_control,
make_host_buffer_size,
make_read_local_version_info,
make_read_bd_addr,
@@ -237,7 +258,8 @@ static const hci_packet_factory_t interface = {
make_ble_read_suggested_default_data_length,
make_ble_write_suggested_default_data_length,
make_ble_set_event_mask,
- make_write_sync_flow_control_enable
+ make_write_sync_flow_control_enable,
+ make_write_default_erroneous_data_report,
};
const hci_packet_factory_t *hci_packet_factory_get_interface()
diff --git a/components/bt/bluedroid/hci/include/hci/hci_packet_factory.h b/components/bt/bluedroid/hci/include/hci/hci_packet_factory.h
index 0cc4dc6849..21bd2c9a62 100644
--- a/components/bt/bluedroid/hci/include/hci/hci_packet_factory.h
+++ b/components/bt/bluedroid/hci/include/hci/hci_packet_factory.h
@@ -25,6 +25,7 @@
typedef struct {
BT_HDR *(*make_reset)(void);
BT_HDR *(*make_read_buffer_size)(void);
+ BT_HDR *(*make_set_c2h_flow_control)(uint8_t enable);
BT_HDR *(*make_host_buffer_size)(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count);
BT_HDR *(*make_read_local_version_info)(void);
BT_HDR *(*make_read_bd_addr)(void);
@@ -43,6 +44,7 @@ typedef struct {
BT_HDR *(*make_ble_write_suggested_default_data_length)(uint16_t SuggestedMaxTxOctets, uint16_t SuggestedMaxTxTime);
BT_HDR *(*make_ble_set_event_mask)(const bt_event_mask_t *event_mask);
BT_HDR *(*make_write_sync_flow_control_enable)(uint8_t enable);
+ BT_HDR *(*make_write_default_erroneous_data_report)(uint8_t enable);
} hci_packet_factory_t;
const hci_packet_factory_t *hci_packet_factory_get_interface();
diff --git a/components/bt/bluedroid/osi/include/osi/fixed_queue.h b/components/bt/bluedroid/osi/include/osi/fixed_queue.h
index e3bf2f67b5..5ec0c07498 100644
--- a/components/bt/bluedroid/osi/include/osi/fixed_queue.h
+++ b/components/bt/bluedroid/osi/include/osi/fixed_queue.h
@@ -22,6 +22,10 @@
#include
#include "osi/list.h"
+#ifndef QUEUE_SIZE_MAX
+#define QUEUE_SIZE_MAX 254
+#endif
+
struct fixed_queue_t;
typedef struct fixed_queue_t fixed_queue_t;
diff --git a/components/bt/bluedroid/osi/include/osi/thread.h b/components/bt/bluedroid/osi/include/osi/thread.h
index 8bb2fdc7c0..1aa773c018 100644
--- a/components/bt/bluedroid/osi/include/osi/thread.h
+++ b/components/bt/bluedroid/osi/include/osi/thread.h
@@ -69,7 +69,7 @@ typedef enum {
#define HCI_H4_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
#define HCI_H4_TASK_PRIO (configMAX_PRIORITIES - 4)
#define HCI_H4_TASK_NAME "hciH4T"
-#define HCI_H4_QUEUE_LEN 60
+#define HCI_H4_QUEUE_LEN 1
#define BTU_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define BTU_TASK_STACK_SIZE (4096 + BT_TASK_EXTRA_STACK_SIZE)
diff --git a/components/bt/bluedroid/stack/avct/avct_lcb.c b/components/bt/bluedroid/stack/avct/avct_lcb.c
index 7d5ba3a16e..61f6c9a556 100644
--- a/components/bt/bluedroid/stack/avct/avct_lcb.c
+++ b/components/bt/bluedroid/stack/avct/avct_lcb.c
@@ -313,7 +313,7 @@ tAVCT_LCB *avct_lcb_alloc(BD_ADDR bd_addr)
p_lcb->allocated = (UINT8)(i + 1);
memcpy(p_lcb->peer_addr, bd_addr, BD_ADDR_LEN);
AVCT_TRACE_DEBUG("avct_lcb_alloc %d", p_lcb->allocated);
- p_lcb->tx_q = fixed_queue_new(SIZE_MAX);
+ p_lcb->tx_q = fixed_queue_new(QUEUE_SIZE_MAX);
break;
}
}
diff --git a/components/bt/bluedroid/stack/avdt/avdt_ccb.c b/components/bt/bluedroid/stack/avdt/avdt_ccb.c
index 5e1a1f46de..035488f854 100644
--- a/components/bt/bluedroid/stack/avdt/avdt_ccb.c
+++ b/components/bt/bluedroid/stack/avdt/avdt_ccb.c
@@ -376,8 +376,8 @@ tAVDT_CCB *avdt_ccb_alloc(BD_ADDR bd_addr)
if (!p_ccb->allocated) {
p_ccb->allocated = TRUE;
memcpy(p_ccb->peer_addr, bd_addr, BD_ADDR_LEN);
- p_ccb->cmd_q = fixed_queue_new(SIZE_MAX);
- p_ccb->rsp_q = fixed_queue_new(SIZE_MAX);
+ p_ccb->cmd_q = fixed_queue_new(QUEUE_SIZE_MAX);
+ p_ccb->rsp_q = fixed_queue_new(QUEUE_SIZE_MAX);
p_ccb->timer_entry.param = (UINT32) p_ccb;
AVDT_TRACE_DEBUG("avdt_ccb_alloc %d\n", i);
break;
diff --git a/components/bt/bluedroid/stack/avdt/avdt_l2c.c b/components/bt/bluedroid/stack/avdt/avdt_l2c.c
index 92e3dcad9d..3227fa69b3 100644
--- a/components/bt/bluedroid/stack/avdt/avdt_l2c.c
+++ b/components/bt/bluedroid/stack/avdt/avdt_l2c.c
@@ -412,6 +412,7 @@ void avdt_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed)
{
tAVDT_TC_TBL *p_tbl;
UINT16 disc_rsn = AVDT_DISC_RSN_NORMAL;
+ tAVDT_CCB *p_ccb;
AVDT_TRACE_DEBUG("avdt_l2c_disconnect_ind_cback lcid: %d, ack_needed: %d\n",
lcid, ack_needed);
/* look up info for this channel */
@@ -420,7 +421,13 @@ void avdt_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed)
/* send L2CAP disconnect response */
L2CA_DisconnectRsp(lcid);
} else {
- disc_rsn = AVDT_DISC_RSN_ABNORMAL;
+ if ((p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx)) != NULL) {
+ UINT16 rsn = L2CA_GetDisconnectReason(p_ccb->peer_addr, BT_TRANSPORT_BR_EDR);
+ if (rsn != 0 && rsn != HCI_ERR_PEER_USER) {
+ disc_rsn = AVDT_DISC_RSN_ABNORMAL;
+ AVDT_TRACE_EVENT("avdt link disc rsn 0x%x", rsn);
+ }
+ }
}
avdt_ad_tc_close_ind(p_tbl, disc_rsn);
diff --git a/components/bt/bluedroid/stack/avdt/avdt_scb.c b/components/bt/bluedroid/stack/avdt/avdt_scb.c
index cf3c1ad331..ac6cbce388 100644
--- a/components/bt/bluedroid/stack/avdt/avdt_scb.c
+++ b/components/bt/bluedroid/stack/avdt/avdt_scb.c
@@ -603,7 +603,7 @@ tAVDT_SCB *avdt_scb_alloc(tAVDT_CS *p_cs)
memcpy(&p_scb->cs, p_cs, sizeof(tAVDT_CS));
#if AVDT_MULTIPLEXING == TRUE
/* initialize fragments gueue */
- p_scb->frag_q = fixed_queue_new(SIZE_MAX);
+ p_scb->frag_q = fixed_queue_new(QUEUE_SIZE_MAX);
if (p_cs->cfg.psc_mask & AVDT_PSC_MUX) {
p_scb->cs.cfg.mux_tcid_media = avdt_ad_type_to_tcid(AVDT_CHAN_MEDIA, p_scb);
diff --git a/components/bt/bluedroid/stack/btm/btm_acl.c b/components/bt/bluedroid/stack/btm/btm_acl.c
index 84fa0d6b71..5bf59c895c 100644
--- a/components/bt/bluedroid/stack/btm/btm_acl.c
+++ b/components/bt/bluedroid/stack/btm/btm_acl.c
@@ -1905,14 +1905,10 @@ void btm_qos_setup_complete (UINT8 status, UINT16 handle, FLOW_SPEC *p_flow)
** Returns BTM_CMD_STARTED if successfully initiated or error code
**
*******************************************************************************/
-tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
+tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb)
{
tACL_CONN *p;
- tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
-#if BLE_INCLUDED == TRUE
- tBT_DEVICE_TYPE dev_type;
- tBLE_ADDR_TYPE addr_type;
-#endif
+
BTM_TRACE_API ("BTM_ReadRSSI: RemBdAddr: %02x%02x%02x%02x%02x%02x\n",
remote_bda[0], remote_bda[1], remote_bda[2],
remote_bda[3], remote_bda[4], remote_bda[5]);
@@ -1924,13 +1920,6 @@ tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
return (BTM_BUSY);
}
-#if BLE_INCLUDED == TRUE
- BTM_ReadDevInfo(remote_bda, &dev_type, &addr_type);
- if (dev_type == BT_DEVICE_TYPE_BLE) {
- transport = BT_TRANSPORT_LE;
- }
-#endif
-
p = btm_bda_to_acl(remote_bda, transport);
if (p != (tACL_CONN *)NULL) {
btu_start_timer (&btm_cb.devcb.rssi_timer, BTU_TTYPE_BTM_ACL,
diff --git a/components/bt/bluedroid/stack/btm/btm_ble.c b/components/bt/bluedroid/stack/btm/btm_ble.c
index 2d3c751724..765265fe1e 100644
--- a/components/bt/bluedroid/stack/btm/btm_ble.c
+++ b/components/bt/bluedroid/stack/btm/btm_ble.c
@@ -1105,7 +1105,7 @@ BOOLEAN btm_ble_get_enc_key_type(BD_ADDR bd_addr, UINT8 *p_key_types)
**
** Description This function is called to read the local DIV
**
-** Returns TURE - if a valid DIV is availavle
+** Returns TRUE - if a valid DIV is availavle
*******************************************************************************/
BOOLEAN btm_get_local_div (BD_ADDR bd_addr, UINT16 *p_div)
{
@@ -1225,7 +1225,7 @@ void btm_sec_save_le_key(BD_ADDR bd_addr, tBTM_LE_KEY_TYPE key_type, tBTM_LE_KEY
/* Set that link key is known since this shares field with BTM_SEC_FLAG_LKEY_KNOWN flag in stack/btm_api.h*/
p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_KNOWN;
- if ( p_keys->pcsrk_key.sec_level == SMP_SEC_AUTHENTICATED) {
+ if ( p_keys->lenc_key.sec_level == SMP_SEC_AUTHENTICATED) {
p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED;
} else {
p_rec->sec_flags &= ~BTM_SEC_LE_LINK_KEY_AUTHED;
@@ -1948,14 +1948,6 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced)
handle = HCID_GET_HANDLE (handle);
btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type, match);
- if(role == HCI_ROLE_SLAVE) {
- //clear p_cb->state, controller will stop adv when ble connected.
- tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
- if(p_cb) {
- p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
- p_cb->state = BTM_BLE_STOP_ADV;
- }
- }
l2cble_conn_comp (handle, role, bda, bda_type, conn_interval,
conn_latency, conn_timeout);
diff --git a/components/bt/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/bluedroid/stack/btm/btm_ble_gap.c
index 109a816896..d36e32a111 100644
--- a/components/bt/bluedroid/stack/btm/btm_ble_gap.c
+++ b/components/bt/bluedroid/stack/btm/btm_ble_gap.c
@@ -3457,15 +3457,21 @@ tBTM_STATUS btm_ble_start_adv(void)
btm_execute_wl_dev_operation();
btm_cb.ble_ctr_cb.wl_state |= BTM_BLE_WL_ADV;
}
-
+ /* The complete event comes up immediately after the 'btsnd_hcic_ble_set_adv_enable' being called in dual core,
+ this causes the 'adv_mode' and 'state' not be set yet, so we set the state first */
+ tBTM_BLE_GAP_STATE temp_state = p_cb->state;
+ UINT8 adv_mode = p_cb->adv_mode;
+ p_cb->adv_mode = BTM_BLE_ADV_ENABLE;
+ p_cb->state = BTM_BLE_ADV_PENDING;
+ btm_ble_adv_states_operation(btm_ble_set_topology_mask, p_cb->evt_type);
if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE)) {
- p_cb->adv_mode = BTM_BLE_ADV_ENABLE;
- p_cb->state = BTM_BLE_ADV_PENDING;
- btm_ble_adv_states_operation(btm_ble_set_topology_mask, p_cb->evt_type);
rt = BTM_SUCCESS;
BTM_TRACE_EVENT ("BTM_SUCCESS\n");
} else {
p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
+ p_cb->state = temp_state;
+ p_cb->adv_mode = adv_mode;
+ btm_ble_adv_states_operation(btm_ble_clear_topology_mask, p_cb->evt_type);
btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
}
return rt;
@@ -3486,15 +3492,30 @@ tBTM_STATUS btm_ble_stop_adv(void)
tBTM_STATUS rt = BTM_SUCCESS;
if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
- if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE)) {
- p_cb->fast_adv_on = FALSE;
- p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
- p_cb->state = BTM_BLE_ADV_PENDING;
- btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
+ UINT8 temp_adv_mode = p_cb->adv_mode;
+ BOOLEAN temp_fast_adv_on = p_cb->fast_adv_on;
+ tBTM_BLE_GAP_STATE temp_state = p_cb->state;
+ tBTM_BLE_WL_STATE temp_wl_state = btm_cb.ble_ctr_cb.wl_state;
+ tBTM_BLE_STATE_MASK temp_mask = btm_ble_get_topology_mask ();
+
+ p_cb->fast_adv_on = FALSE;
+ p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
+ p_cb->state = BTM_BLE_ADV_PENDING;
+ btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
+
+ /* clear all adv states */
+ btm_ble_clear_topology_mask (BTM_BLE_STATE_ALL_ADV_MASK);
+
+ if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE)) {
- /* clear all adv states */
- btm_ble_clear_topology_mask (BTM_BLE_STATE_ALL_ADV_MASK);
} else {
+ // reset state
+ p_cb->fast_adv_on = temp_fast_adv_on;
+ p_cb->adv_mode = temp_adv_mode;
+ p_cb->state = temp_state;
+ btm_cb.ble_ctr_cb.wl_state = temp_wl_state;
+ btm_ble_set_topology_mask (temp_mask);
+
rt = BTM_NO_RESOURCES;
}
}
@@ -3739,6 +3760,20 @@ BOOLEAN btm_ble_clear_topology_mask (tBTM_BLE_STATE_MASK request_state_mask)
return TRUE;
}
+/*******************************************************************************
+**
+** Function btm_ble_get_topology_mask
+**
+** Description Get BLE topology bit mask
+**
+** Returns state mask.
+**
+*******************************************************************************/
+tBTM_BLE_STATE_MASK btm_ble_get_topology_mask (void)
+{
+ return btm_cb.ble_ctr_cb.cur_states;
+}
+
/*******************************************************************************
**
** Function btm_ble_update_link_topology_mask
@@ -3832,7 +3867,7 @@ void btm_ble_init (void)
btm_cb.cmn_ble_vsc_cb.values_read = FALSE;
p_cb->cur_states = 0;
- p_cb->conn_pending_q = fixed_queue_new(SIZE_MAX);
+ p_cb->conn_pending_q = fixed_queue_new(QUEUE_SIZE_MAX);
p_cb->inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
p_cb->inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
diff --git a/components/bt/bluedroid/stack/btm/btm_dev.c b/components/bt/bluedroid/stack/btm/btm_dev.c
index c7427863ea..d8073e112e 100644
--- a/components/bt/bluedroid/stack/btm/btm_dev.c
+++ b/components/bt/bluedroid/stack/btm/btm_dev.c
@@ -172,22 +172,23 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
** Description Free resources associated with the device.
**
** Parameters: bd_addr - BD address of the peer
+** transport - BT_TRANSPORT_BR_EDR or BT_TRANSPORT_LE
**
** Returns TRUE if removed OK, FALSE if not found or ACL link is active
**
*******************************************************************************/
-BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr)
+BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr, tBT_TRANSPORT transport)
{
+
tBTM_SEC_DEV_REC *p_dev_rec;
- if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) ||
- BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR)) {
+ if (BTM_IsAclConnectionUp(bd_addr, transport)) {
BTM_TRACE_WARNING("%s FAILED: Cannot Delete when connection is active\n", __func__);
return FALSE;
}
-
if ((p_dev_rec = btm_find_dev(bd_addr)) != NULL) {
- btm_sec_free_dev(p_dev_rec);
+ btm_sec_free_dev(p_dev_rec, transport);
+
/* Tell controller to get rid of the link key, if it has one stored */
BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL);
}
@@ -340,17 +341,33 @@ tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr)
** Description Mark device record as not used
**
*******************************************************************************/
-void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec)
+void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec, tBT_TRANSPORT transport)
{
- p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;
- p_dev_rec->sec_flags = 0;
+ if (transport == BT_TRANSPORT_BR_EDR) {
+ memset(p_dev_rec->link_key, 0, LINK_KEY_LEN);
+ p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED
+ | BTM_SEC_ENCRYPTED | BTM_SEC_NAME_KNOWN
+ | BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED
+ | BTM_SEC_ROLE_SWITCHED | BTM_SEC_16_DIGIT_PIN_AUTHED);
+ } else if (transport == BT_TRANSPORT_LE) {
+ p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;
+ p_dev_rec->sec_flags &= ~(BTM_SEC_LE_AUTHENTICATED | BTM_SEC_LE_ENCRYPTED
+ | BTM_SEC_LE_NAME_KNOWN | BTM_SEC_LE_LINK_KEY_KNOWN
+ | BTM_SEC_LE_LINK_KEY_AUTHED | BTM_SEC_ROLE_SWITCHED);
+#if BLE_INCLUDED == TRUE
+ /* Clear out any saved BLE keys */
+ btm_sec_clear_ble_keys (p_dev_rec);
+#endif
+ } else {
+ p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;
+ memset(p_dev_rec->link_key, 0, LINK_KEY_LEN);
+ p_dev_rec->sec_flags = 0;
#if BLE_INCLUDED == TRUE
- /* Clear out any saved BLE keys */
- btm_sec_clear_ble_keys (p_dev_rec);
+ /* Clear out any saved BLE keys */
+ btm_sec_clear_ble_keys (p_dev_rec);
#endif
-
-
+ }
}
/*******************************************************************************
diff --git a/components/bt/bluedroid/stack/btm/btm_main.c b/components/bt/bluedroid/stack/btm/btm_main.c
index d1ba6acba6..579e8d6453 100644
--- a/components/bt/bluedroid/stack/btm/btm_main.c
+++ b/components/bt/bluedroid/stack/btm/btm_main.c
@@ -56,8 +56,8 @@ void btm_init (void)
#endif /* #if BTM_DYNAMIC_MEMORY */
/* All fields are cleared; nonzero fields are reinitialized in appropriate function */
memset(&btm_cb, 0, sizeof(tBTM_CB));
- btm_cb.page_queue = fixed_queue_new(SIZE_MAX);
- btm_cb.sec_pending_q = fixed_queue_new(SIZE_MAX);
+ btm_cb.page_queue = fixed_queue_new(QUEUE_SIZE_MAX);
+ btm_cb.sec_pending_q = fixed_queue_new(QUEUE_SIZE_MAX);
#if defined(BTM_INITIAL_TRACE_LEVEL)
btm_cb.trace_level = BTM_INITIAL_TRACE_LEVEL;
diff --git a/components/bt/bluedroid/stack/btm/btm_sco.c b/components/bt/bluedroid/stack/btm/btm_sco.c
index e04209aab5..6b8a32befd 100644
--- a/components/bt/bluedroid/stack/btm/btm_sco.c
+++ b/components/bt/bluedroid/stack/btm/btm_sco.c
@@ -113,7 +113,7 @@ void btm_sco_init (void)
#endif
#if (BTM_SCO_HCI_INCLUDED == TRUE)
for (int i = 0; i < BTM_MAX_SCO_LINKS; i++) {
- btm_cb.sco_cb.sco_db[i].xmit_data_q = fixed_queue_new(SIZE_MAX);
+ btm_cb.sco_cb.sco_db[i].xmit_data_q = fixed_queue_new(QUEUE_SIZE_MAX);
}
#endif
/* Initialize nonzero defaults */
@@ -319,9 +319,8 @@ void btm_sco_process_num_completed_pkts (UINT8 *p)
STREAM_TO_UINT8 (num_handles, p);
for (xx = 0; xx < num_handles; xx++) {
STREAM_TO_UINT16 (handle, p);
- handle &= 0x7ff; // walk around for bad handle bit mask from controller
STREAM_TO_UINT16 (num_sent, p);
- if ((sco_inx = btm_find_scb_by_handle(handle & 0x7ff)) == BTM_MAX_SCO_LINKS) {
+ if ((sco_inx = btm_find_scb_by_handle(handle)) == BTM_MAX_SCO_LINKS) {
continue;
}
BTM_TRACE_DEBUG("%s, %d, %u", __FUNCTION__, handle, p_cb->xmit_window_size); //debug
diff --git a/components/bt/bluedroid/stack/btm/btm_sec.c b/components/bt/bluedroid/stack/btm/btm_sec.c
index 71d888902d..29b2ac50ff 100644
--- a/components/bt/bluedroid/stack/btm/btm_sec.c
+++ b/components/bt/bluedroid/stack/btm/btm_sec.c
@@ -1361,7 +1361,7 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, tBTM_SE
return (BTM_SUCCESS);
}
-
+ p_dev_rec->enc_init_by_we = TRUE;
/* enqueue security request if security is active */
if (p_dev_rec->p_callback || (p_dev_rec->sec_state != BTM_SEC_STATE_IDLE)) {
BTM_TRACE_WARNING ("Security Manager: BTM_SetEncryption busy, enqueue request\n");
@@ -1524,7 +1524,7 @@ void BTM_ConfirmReqReply(tBTM_STATUS res, BD_ADDR bd_addr)
** BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
**
*******************************************************************************/
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE && SMP_INCLUDED == TRUE)
+#if (BT_SSP_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr, UINT32 passkey)
{
#if (BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE)
@@ -1572,7 +1572,7 @@ void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr, UINT32 passkey)
btsnd_hcic_user_passkey_reply (bd_addr, passkey);
}
}
-#endif ///BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE && SMP_INCLUDED == TRUE
+#endif ///BT_SSP_INCLUDED == TRUE && SMP_INCLUDED == TRUE
/*******************************************************************************
**
@@ -1588,7 +1588,7 @@ void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr, UINT32 passkey)
** type - notification type
**
*******************************************************************************/
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE && SMP_INCLUDED == TRUE)
+#if (BT_SSP_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
void BTM_SendKeypressNotif(BD_ADDR bd_addr, tBTM_SP_KEY_TYPE type)
{
/* This API only make sense between PASSKEY_REQ and SP complete */
@@ -1596,7 +1596,7 @@ void BTM_SendKeypressNotif(BD_ADDR bd_addr, tBTM_SP_KEY_TYPE type)
btsnd_hcic_send_keypress_notif (bd_addr, type);
}
}
-#endif ///BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE && SMP_INCLUDED == TRUE
+#endif ///BT_SSP_INCLUDED == TRUE && SMP_INCLUDED == TRUE
#if BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE
/*******************************************************************************
@@ -2762,7 +2762,7 @@ void btm_sec_check_pending_reqs (void)
/* Now, re-submit anything in the mux queue */
bq = btm_cb.sec_pending_q;
if (!btm_cb.sec_pending_q) {
- btm_cb.sec_pending_q = fixed_queue_new(SIZE_MAX);
+ btm_cb.sec_pending_q = fixed_queue_new(QUEUE_SIZE_MAX);
}
while ((p_e = (tBTM_SEC_QUEUE_ENTRY *)fixed_queue_try_dequeue(bq)) != NULL) {
@@ -3504,7 +3504,7 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
evt_data.cfm_req.just_works = TRUE;
/* process user confirm req in association with the auth_req param */
-#if (BTM_LOCAL_IO_CAPS == BTM_IO_CAP_IO)
+// #if (BTM_LOCAL_IO_CAPS == BTM_IO_CAP_IO)
if ( (p_dev_rec->rmt_io_caps == BTM_IO_CAP_IO)
&& (btm_cb.devcb.loc_io_caps == BTM_IO_CAP_IO)
&& ((p_dev_rec->rmt_auth_req & BTM_AUTH_SP_YES) || (btm_cb.devcb.loc_auth_req & BTM_AUTH_SP_YES)) ) {
@@ -3512,7 +3512,7 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
-> use authenticated link key */
evt_data.cfm_req.just_works = FALSE;
}
-#endif
+// #endif
BTM_TRACE_DEBUG ("btm_proc_sp_req_evt() just_works:%d, io loc:%d, rmt:%d, auth loc:%d, rmt:%d\n",
evt_data.cfm_req.just_works, btm_cb.devcb.loc_io_caps, p_dev_rec->rmt_io_caps,
btm_cb.devcb.loc_auth_req, p_dev_rec->rmt_auth_req);
@@ -3532,7 +3532,7 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
break;
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
case BTM_SP_KEY_REQ_EVT:
/* HCI_USER_PASSKEY_REQUEST_EVT */
btm_sec_change_pairing_state (BTM_PAIR_STATE_KEY_ENTRY);
@@ -3555,14 +3555,13 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
BTM_TRACE_DEBUG ("calling BTM_ConfirmReqReply with status: %d\n", status);
BTM_ConfirmReqReply (status, p_bda);
}
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
else if (event == BTM_SP_KEY_REQ_EVT) {
BTM_PasskeyReqReply(status, p_bda, 0);
}
#endif
return;
}
-
/* Something bad. we can only fail this connection */
btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
@@ -3579,7 +3578,8 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
btm_sec_disconnect (p_dev_rec->hci_handle, HCI_ERR_AUTH_FAILURE);
}
}
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+
+#if (BT_SSP_INCLUDED == TRUE)
else {
btsnd_hcic_user_passkey_neg_reply(p_bda);
}
@@ -4018,7 +4018,6 @@ void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
tACL_CONN *p_acl = NULL;
UINT8 acl_idx = btm_handle_to_acl_index(handle);
- tGATT_TCB *p_tcb = NULL;
#endif
BTM_TRACE_EVENT ("Security Manager: encrypt_change status:%d State:%d, encr_enable = %d\n",
status, (p_dev_rec) ? p_dev_rec->sec_state : 0, encr_enable);
@@ -4046,11 +4045,6 @@ void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
p_dev_rec->sec_flags |= BTM_SEC_16_DIGIT_PIN_AUTHED;
}
} else {
-#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
- if ((p_tcb = gatt_find_tcb_by_addr(p_dev_rec->ble.pseudo_addr, BT_TRANSPORT_LE)) == NULL) {
- //do nothing
- } else
-#endif
p_dev_rec->sec_flags |= (BTM_SEC_LE_AUTHENTICATED | BTM_SEC_LE_ENCRYPTED);
}
}
@@ -4540,7 +4534,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason)
if (!p_dev_rec) {
return;
}
-
+ p_dev_rec->enc_init_by_we = FALSE;
transport = (handle == p_dev_rec->hci_handle) ? BT_TRANSPORT_BR_EDR : BT_TRANSPORT_LE;
p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
@@ -4846,7 +4840,7 @@ static void btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle)
/* btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); */
break;
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
case BTM_PAIR_STATE_KEY_ENTRY:
btsnd_hcic_user_passkey_neg_reply(p_cb->pairing_bda);
/* btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); */
diff --git a/components/bt/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/bluedroid/stack/btm/include/btm_ble_int.h
index a9f0d8ff68..1a8aed28e4 100644
--- a/components/bt/bluedroid/stack/btm/include/btm_ble_int.h
+++ b/components/bt/bluedroid/stack/btm/include/btm_ble_int.h
@@ -481,6 +481,7 @@ void btm_ble_adv_filter_cleanup(void);
BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request);
BOOLEAN btm_ble_clear_topology_mask(tBTM_BLE_STATE_MASK request_state);
BOOLEAN btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state);
+tBTM_BLE_STATE_MASK btm_ble_get_topology_mask(void);
#if BTM_BLE_CONFORMANCE_TESTING == TRUE
void btm_ble_set_no_disc_if_pair_fail (BOOLEAN disble_disc);
diff --git a/components/bt/bluedroid/stack/btm/include/btm_int.h b/components/bt/bluedroid/stack/btm/include/btm_int.h
index bde7af9a2e..1dcaac4508 100644
--- a/components/bt/bluedroid/stack/btm/include/btm_int.h
+++ b/components/bt/bluedroid/stack/btm/include/btm_int.h
@@ -491,10 +491,10 @@ typedef struct {
bool skip_update_conn_param; /* skip update connection paraams or not*/
#endif
#if (BLE_PRIVACY_SPT == TRUE)
- tBLE_ADDR_TYPE current_addr_type; /* current adv addr type*/
+ tBLE_ADDR_TYPE current_addr_type; /* current adv addr type*/
BD_ADDR current_addr; /* current adv addr*/
bool current_addr_valid; /* current addr info is valid or not*/
-#endif
+#endif
} tBTM_SEC_BLE;
@@ -618,7 +618,7 @@ typedef struct {
// btla-specific --
#define BTM_SEC_NO_LAST_SERVICE_ID 0
UINT8 last_author_service_id; /* ID of last serviced authorized: Reset after each l2cap connection */
-
+ BOOLEAN enc_init_by_we;
} tBTM_SEC_DEV_REC;
#define BTM_SEC_IS_SM4(sm) ((BOOLEAN)(BTM_SM4_TRUE == ((sm)&BTM_SM4_TRUE)))
@@ -1062,7 +1062,7 @@ void btm_report_device_status (tBTM_DEV_STATUS status);
BOOLEAN btm_dev_support_switch (BD_ADDR bd_addr);
tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr);
-void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec);
+void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec, tBT_TRANSPORT transport);
tBTM_SEC_DEV_REC *btm_find_dev (BD_ADDR bd_addr);
tBTM_SEC_DEV_REC *btm_find_or_alloc_dev (BD_ADDR bd_addr);
tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle);
diff --git a/components/bt/bluedroid/stack/btu/btu_init.c b/components/bt/bluedroid/stack/btu/btu_init.c
index bf04bd14dd..7014cfde00 100644
--- a/components/bt/bluedroid/stack/btu/btu_init.c
+++ b/components/bt/bluedroid/stack/btu/btu_init.c
@@ -236,3 +236,13 @@ UINT16 BTU_BleAclPktSize(void)
return 0;
#endif
}
+#if SCAN_QUEUE_CONGEST_CHECK
+bool BTU_check_queue_is_congest(void)
+{
+ UBaseType_t wait_size = uxQueueMessagesWaiting(xBtuQueue);
+ if(wait_size >= QUEUE_CONGEST_SIZE ) {
+ return true;
+ }
+ return false;
+}
+#endif
diff --git a/components/bt/bluedroid/stack/gap/gap_conn.c b/components/bt/bluedroid/stack/gap/gap_conn.c
index ecb7b726f5..671ffa7427 100644
--- a/components/bt/bluedroid/stack/gap/gap_conn.c
+++ b/components/bt/bluedroid/stack/gap/gap_conn.c
@@ -1120,8 +1120,8 @@ static tGAP_CCB *gap_allocate_ccb (void)
for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++) {
if (p_ccb->con_state == GAP_CCB_STATE_IDLE) {
memset (p_ccb, 0, sizeof (tGAP_CCB));
- p_ccb->tx_queue = fixed_queue_new(SIZE_MAX);
- p_ccb->rx_queue = fixed_queue_new(SIZE_MAX);
+ p_ccb->tx_queue = fixed_queue_new(QUEUE_SIZE_MAX);
+ p_ccb->rx_queue = fixed_queue_new(QUEUE_SIZE_MAX);
p_ccb->gap_handle = xx;
p_ccb->rem_mtu_size = L2CAP_MTU_SIZE;
diff --git a/components/bt/bluedroid/stack/gatt/att_protocol.c b/components/bt/bluedroid/stack/gatt/att_protocol.c
index 3adecfaef6..adbedab524 100644
--- a/components/bt/bluedroid/stack/gatt/att_protocol.c
+++ b/components/bt/bluedroid/stack/gatt/att_protocol.c
@@ -354,7 +354,7 @@ tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB *p_tcb, BT_HDR *p_toL2CAP)
}
if (l2cap_ret == L2CAP_DW_FAILED) {
- GATT_TRACE_ERROR("ATT failed to pass msg:0x%0x to L2CAP",
+ GATT_TRACE_DEBUG("ATT failed to pass msg:0x%0x to L2CAP",
*((UINT8 *)(p_toL2CAP + 1) + p_toL2CAP->offset));
return GATT_INTERNAL_ERROR;
} else if (l2cap_ret == L2CAP_DW_CONGESTED) {
diff --git a/components/bt/bluedroid/stack/gatt/gatt_db.c b/components/bt/bluedroid/stack/gatt/gatt_db.c
index 0a3a104a4b..46c5104c83 100644
--- a/components/bt/bluedroid/stack/gatt/gatt_db.c
+++ b/components/bt/bluedroid/stack/gatt/gatt_db.c
@@ -64,7 +64,7 @@ BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN
UINT16 s_hdl, UINT16 num_handle)
{
if (p_db->svc_buffer == NULL) { //in case already alloc
- p_db->svc_buffer = fixed_queue_new(SIZE_MAX);
+ p_db->svc_buffer = fixed_queue_new(QUEUE_SIZE_MAX);
}
if (!allocate_svc_db_buf(p_db)) {
diff --git a/components/bt/bluedroid/stack/gatt/gatt_main.c b/components/bt/bluedroid/stack/gatt/gatt_main.c
index 82059afd31..add39455fe 100644
--- a/components/bt/bluedroid/stack/gatt/gatt_main.c
+++ b/components/bt/bluedroid/stack/gatt/gatt_main.c
@@ -108,9 +108,9 @@ void gatt_init (void)
gatt_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
#endif
gatt_cb.def_mtu_size = GATT_DEF_BLE_MTU_SIZE;
- gatt_cb.sign_op_queue = fixed_queue_new(SIZE_MAX);
- gatt_cb.srv_chg_clt_q = fixed_queue_new(SIZE_MAX);
- gatt_cb.pending_new_srv_start_q = fixed_queue_new(SIZE_MAX);
+ gatt_cb.sign_op_queue = fixed_queue_new(QUEUE_SIZE_MAX);
+ gatt_cb.srv_chg_clt_q = fixed_queue_new(QUEUE_SIZE_MAX);
+ gatt_cb.pending_new_srv_start_q = fixed_queue_new(QUEUE_SIZE_MAX);
/* First, register fixed L2CAP channel for ATT over BLE */
fixed_reg.fixed_chnl_opts.mode = L2CAP_FCR_BASIC_MODE;
fixed_reg.fixed_chnl_opts.max_transmit = 0xFF;
@@ -179,7 +179,7 @@ void gatt_free(void)
btu_free_timer(&gatt_cb.tcb[i].ind_ack_timer_ent);
memset(&gatt_cb.tcb[i].ind_ack_timer_ent, 0, sizeof(TIMER_LIST_ENT));
-
+
#if (GATTS_INCLUDED == TRUE)
fixed_queue_free(gatt_cb.tcb[i].sr_cmd.multi_rsp_q, NULL);
gatt_cb.tcb[i].sr_cmd.multi_rsp_q = NULL;
@@ -979,7 +979,12 @@ void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf)
}
}
} else {
- GATT_TRACE_ERROR ("ATT - Rcvd L2CAP data, unknown cmd: 0x%x\n", op_code);
+ if (op_code & GATT_COMMAND_FLAG) {
+ GATT_TRACE_ERROR ("ATT - Rcvd L2CAP data, unknown cmd: 0x%x\n", op_code);
+ } else {
+ GATT_TRACE_ERROR ("ATT - Rcvd L2CAP data, unknown req: 0x%x\n", op_code);
+ gatt_send_error_rsp (p_tcb, GATT_REQ_NOT_SUPPORTED, op_code, 0, FALSE);
+ }
}
} else {
GATT_TRACE_ERROR ("invalid data length, ignore\n");
diff --git a/components/bt/bluedroid/stack/gatt/gatt_sr.c b/components/bt/bluedroid/stack/gatt/gatt_sr.c
index 697540d4c1..24df5a4eb3 100644
--- a/components/bt/bluedroid/stack/gatt/gatt_sr.c
+++ b/components/bt/bluedroid/stack/gatt/gatt_sr.c
@@ -167,7 +167,7 @@ static BOOLEAN process_read_multi_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS status,
GATT_TRACE_DEBUG ("process_read_multi_rsp status=%d mtu=%d", status, mtu);
if (p_cmd->multi_rsp_q == NULL) {
- p_cmd->multi_rsp_q = fixed_queue_new(SIZE_MAX);
+ p_cmd->multi_rsp_q = fixed_queue_new(QUEUE_SIZE_MAX);
}
/* Enqueue the response */
@@ -1290,7 +1290,7 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand
queue_data->offset = offset;
memcpy(queue_data->value, p, len);
if (prepare_record->queue == NULL) {
- prepare_record->queue = fixed_queue_new(SIZE_MAX);
+ prepare_record->queue = fixed_queue_new(QUEUE_SIZE_MAX);
}
fixed_queue_enqueue(prepare_record->queue, queue_data);
}
diff --git a/components/bt/bluedroid/stack/gatt/gatt_utils.c b/components/bt/bluedroid/stack/gatt/gatt_utils.c
index 95efcf6763..12a2e1dba3 100644
--- a/components/bt/bluedroid/stack/gatt/gatt_utils.c
+++ b/components/bt/bluedroid/stack/gatt/gatt_utils.c
@@ -337,7 +337,7 @@ tGATT_HDL_LIST_ELEM *gatt_alloc_hdl_buffer(void)
if (!p_cb->hdl_list[i].in_use) {
memset(p_elem, 0, sizeof(tGATT_HDL_LIST_ELEM));
p_elem->in_use = TRUE;
- p_elem->svc_db.svc_buffer = fixed_queue_new(SIZE_MAX);
+ p_elem->svc_db.svc_buffer = fixed_queue_new(QUEUE_SIZE_MAX);
return p_elem;
}
}
@@ -1007,8 +1007,8 @@ tGATT_TCB *gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport)
if (allocated) {
memset(p_tcb, 0, sizeof(tGATT_TCB));
- p_tcb->pending_enc_clcb = fixed_queue_new(SIZE_MAX);
- p_tcb->pending_ind_q = fixed_queue_new(SIZE_MAX);
+ p_tcb->pending_enc_clcb = fixed_queue_new(QUEUE_SIZE_MAX);
+ p_tcb->pending_ind_q = fixed_queue_new(QUEUE_SIZE_MAX);
p_tcb->in_use = TRUE;
p_tcb->tcb_idx = i;
p_tcb->transport = transport;
diff --git a/components/bt/bluedroid/stack/include/stack/avrc_defs.h b/components/bt/bluedroid/stack/include/stack/avrc_defs.h
index 1933d8a96c..8c56cf5327 100644
--- a/components/bt/bluedroid/stack/include/stack/avrc_defs.h
+++ b/components/bt/bluedroid/stack/include/stack/avrc_defs.h
@@ -47,21 +47,21 @@
/* command type codes */
#define AVRC_CMD_CTRL 0 /* Instruct a target to perform an operation */
-#define AVRC_CMD_STATUS 1 /* Check a devices current status */
+#define AVRC_CMD_STATUS 1 /* Check a devices current status */
#define AVRC_CMD_SPEC_INQ 2 /* Check whether a target supports a particular
control command; all operands are included */
-#define AVRC_CMD_NOTIF 3 /* Used for receiving notification of a change in a devices state */
+#define AVRC_CMD_NOTIF 3 /* Used for receiving notification of a change in a devices state */
#define AVRC_CMD_GEN_INQ 4 /* Check whether a target supports a particular
control command; operands are not included */
/* response type codes */
#define AVRC_RSP_NOT_IMPL 8 /* The target does not implement the command specified
by the opcode and operand,
- or doesnt implement the specified subunit */
+ or doesnt implement the specified subunit */
#define AVRC_RSP_ACCEPT 9 /* The target executed or is executing the command */
#define AVRC_RSP_REJ 10 /* The target implements the command specified by the
opcode but cannot respond because the current state
- of the target doesnt allow it */
+ of the target doesnt allow it */
#define AVRC_RSP_IN_TRANS 11 /* The target implements the status command but it is
in a state of transition; the status command may
be retried at a future time */
@@ -70,7 +70,7 @@
commands, the target returns stable and includes
the status results */
#define AVRC_RSP_CHANGED 13 /* The response frame contains a notification that the
- target devices state has changed */
+ target devices state has changed */
#define AVRC_RSP_INTERIM 15 /* For control commands, the target has accepted the
request but cannot return information within 100
milliseconds; for notify commands, the target accepted
diff --git a/components/bt/bluedroid/stack/include/stack/btm_api.h b/components/bt/bluedroid/stack/include/stack/btm_api.h
index 79ecba8c8f..c483268aec 100644
--- a/components/bt/bluedroid/stack/include/stack/btm_api.h
+++ b/components/bt/bluedroid/stack/include/stack/btm_api.h
@@ -2811,8 +2811,8 @@ tBTM_STATUS BTM_SwitchRole (BD_ADDR remote_bd_addr,
**
** Function BTM_ReadRSSI
**
-** Description This function is called to read the link policy settings.
-** The address of link policy results are returned in the callback.
+** Description This function is called to read the RSSI for a particular transport.
+** The RSSI of results are returned in the callback.
** (tBTM_RSSI_RESULTS)
**
** Returns BTM_CMD_STARTED if command issued to controller.
@@ -2822,7 +2822,7 @@ tBTM_STATUS BTM_SwitchRole (BD_ADDR remote_bd_addr,
**
*******************************************************************************/
//extern
-tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb);
+tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb);
/*******************************************************************************
@@ -3417,8 +3417,7 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class,
**
*******************************************************************************/
//extern
-BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr);
-
+BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr, tBT_TRANSPORT transport);
/*******************************************************************************
**
diff --git a/components/bt/bluedroid/stack/include/stack/gatt_api.h b/components/bt/bluedroid/stack/include/stack/gatt_api.h
index 98cdcc7fa7..24a186ae71 100644
--- a/components/bt/bluedroid/stack/include/stack/gatt_api.h
+++ b/components/bt/bluedroid/stack/include/stack/gatt_api.h
@@ -64,7 +64,7 @@
#define GATT_NOT_ENCRYPTED 0x8e
#define GATT_CONGESTED 0x8f
-#define GATT_DUP_REG 0x90
+#define GATT_DUP_REG 0x90
#define GATT_ALREADY_OPEN 0x91
#define GATT_CANCEL 0x92
@@ -111,6 +111,7 @@ typedef UINT8 tGATT_STATUS;
#define GATT_SIGN_CMD_WRITE 0xD2 /* changed in V4.0 1101-0010 (signed write) see write cmd above*/
#define GATT_OP_CODE_MAX GATT_HANDLE_VALUE_CONF + 1 /* 0x1E = 30 + 1 = 31*/
+#define GATT_COMMAND_FLAG 0x40 /* Command Flag: set to one means commond */
#define GATT_HANDLE_IS_VALID(x) ((x) != 0)
@@ -766,7 +767,7 @@ extern UINT16 GATTS_AddIncludeService (UINT16 service_handle,
**
*******************************************************************************/
extern UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *p_char_uuid,
- tGATT_PERM perm, tGATT_CHAR_PROP property,
+ tGATT_PERM perm, tGATT_CHAR_PROP property,
tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control);
/*******************************************************************************
diff --git a/components/bt/bluedroid/stack/include/stack/hcidefs.h b/components/bt/bluedroid/stack/include/stack/hcidefs.h
index 09320b1f1a..0169ba8cc3 100644
--- a/components/bt/bluedroid/stack/include/stack/hcidefs.h
+++ b/components/bt/bluedroid/stack/include/stack/hcidefs.h
@@ -793,7 +793,7 @@
#define HCI_ERR_MAX_ERR 0x43
//ESP vendor error code
-#define HCI_ERR_ESP_VENDOR_FAIL 0xE0
+#define HCI_ERR_ESP_VENDOR_FAIL 0xE0
#define HCI_HINT_TO_RECREATE_AMP_PHYS_LINK 0xFF
diff --git a/components/bt/bluedroid/stack/l2cap/include/l2c_int.h b/components/bt/bluedroid/stack/l2cap/include/l2c_int.h
index 3699e7f05b..e2c0ef6a76 100644
--- a/components/bt/bluedroid/stack/l2cap/include/l2c_int.h
+++ b/components/bt/bluedroid/stack/l2cap/include/l2c_int.h
@@ -376,6 +376,7 @@ typedef struct t_l2c_linkcb {
TIMER_LIST_ENT timer_entry; /* Timer list entry for timeout evt */
UINT16 handle; /* The handle used with LM */
+ UINT16 completed_packets; /* The number of conpleted packets */
tL2C_CCB_Q ccb_queue; /* Queue of CCBs on this LCB */
@@ -667,6 +668,10 @@ extern void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB *p_ccb);
#endif
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+extern UINT8 l2cu_find_completed_packets(UINT16 *handles, UINT16 *num_packets);
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
extern BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr);
extern void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb);
extern void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb);
diff --git a/components/bt/bluedroid/stack/l2cap/l2c_api.c b/components/bt/bluedroid/stack/l2cap/l2c_api.c
index 654a4df632..5637cac647 100644
--- a/components/bt/bluedroid/stack/l2cap/l2c_api.c
+++ b/components/bt/bluedroid/stack/l2cap/l2c_api.c
@@ -1816,7 +1816,7 @@ UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf)
// If already congested, do not accept any more packets
if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) {
- L2CAP_TRACE_ERROR ("L2CAP - CID: 0x%04x cannot send, already congested\
+ L2CAP_TRACE_DEBUG ("L2CAP - CID: 0x%04x cannot send, already congested\
xmit_hold_q.count: %u buff_quota: %u", fixed_cid,
fixed_queue_length(p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->xmit_hold_q),
p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->buff_quota);
@@ -1887,7 +1887,7 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport);
if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) ) {
- L2CAP_TRACE_WARNING ("L2CA_RemoveFixedChnl() CID: 0x%04x BDA: %08x%04x not connected", fixed_cid,
+ L2CAP_TRACE_DEBUG ("L2CA_RemoveFixedChnl() CID: 0x%04x BDA: %08x%04x not connected", fixed_cid,
(rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3], (rem_bda[4] << 8) + rem_bda[5]);
return (FALSE);
}
diff --git a/components/bt/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/bluedroid/stack/l2cap/l2c_ble.c
index b967295170..7329552106 100644
--- a/components/bt/bluedroid/stack/l2cap/l2c_ble.c
+++ b/components/bt/bluedroid/stack/l2cap/l2c_ble.c
@@ -261,6 +261,15 @@ void l2cble_notify_le_connection (BD_ADDR bda)
tACL_CONN *p_acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE) ;
if (p_lcb != NULL && p_acl != NULL && p_lcb->link_state != LST_CONNECTED) {
+
+ if(p_acl->link_role == HCI_ROLE_SLAVE) {
+ //clear p_cb->state, controller will stop adv when ble connected.
+ tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
+ if(p_cb) {
+ p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
+ p_cb->state = BTM_BLE_STOP_ADV;
+ }
+ }
/* update link status */
btm_establish_continue(p_acl);
/* update l2cap link status and send callback */
diff --git a/components/bt/bluedroid/stack/l2cap/l2c_fcr.c b/components/bt/bluedroid/stack/l2cap/l2c_fcr.c
index cacdcc6f50..33bd0faf8d 100644
--- a/components/bt/bluedroid/stack/l2cap/l2c_fcr.c
+++ b/components/bt/bluedroid/stack/l2cap/l2c_fcr.c
@@ -750,7 +750,7 @@ void l2c_fcr_proc_pdu (tL2C_CCB *p_ccb, BT_HDR *p_buf)
if ( (!p_ccb->fcrb.local_busy) && (!p_ccb->fcrb.srej_sent) &&
(!fixed_queue_is_empty(p_ccb->fcrb.srej_rcv_hold_q))) {
fixed_queue_t *temp_q = p_ccb->fcrb.srej_rcv_hold_q;
- p_ccb->fcrb.srej_rcv_hold_q = fixed_queue_new(SIZE_MAX);
+ p_ccb->fcrb.srej_rcv_hold_q = fixed_queue_new(QUEUE_SIZE_MAX);
while ((p_buf = (BT_HDR *)fixed_queue_try_dequeue(temp_q)) != NULL) {
if (p_ccb->in_use && (p_ccb->chnl_state == CST_OPEN)) {
diff --git a/components/bt/bluedroid/stack/l2cap/l2c_main.c b/components/bt/bluedroid/stack/l2cap/l2c_main.c
index c9f4c4d3b2..0178f4770d 100644
--- a/components/bt/bluedroid/stack/l2cap/l2c_main.c
+++ b/components/bt/bluedroid/stack/l2cap/l2c_main.c
@@ -966,7 +966,7 @@ UINT8 l2c_data_write (UINT16 cid, BT_HDR *p_data, UINT16 flags)
/* If already congested, do not accept any more packets */
if (p_ccb->cong_sent) {
- L2CAP_TRACE_ERROR ("L2CAP - CID: 0x%04x cannot send, already congested xmit_hold_q.count: %u buff_quota: %u",
+ L2CAP_TRACE_DEBUG ("L2CAP - CID: 0x%04x cannot send, already congested xmit_hold_q.count: %u buff_quota: %u",
p_ccb->local_cid,
fixed_queue_length(p_ccb->xmit_hold_q),
p_ccb->buff_quota);
diff --git a/components/bt/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/bluedroid/stack/l2cap/l2c_utils.c
index 358a57b5f4..978e020e65 100644
--- a/components/bt/bluedroid/stack/l2cap/l2c_utils.c
+++ b/components/bt/bluedroid/stack/l2cap/l2c_utils.c
@@ -57,7 +57,7 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPOR
btu_free_timer(&p_lcb->timer_entry);
btu_free_timer(&p_lcb->info_timer_entry);
btu_free_timer(&p_lcb->upda_con_timer);
-
+
memset (p_lcb, 0, sizeof (tL2C_LCB));
memcpy (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN);
@@ -74,7 +74,7 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPOR
#if (BLE_INCLUDED == TRUE)
p_lcb->transport = transport;
p_lcb->tx_data_len = controller_get_interface()->get_ble_default_data_packet_length();
- p_lcb->le_sec_pending_q = fixed_queue_new(SIZE_MAX);
+ p_lcb->le_sec_pending_q = fixed_queue_new(QUEUE_SIZE_MAX);
if (transport == BT_TRANSPORT_LE) {
l2cb.num_ble_links_active++;
@@ -86,6 +86,9 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPOR
l2c_link_adjust_allocation();
}
p_lcb->link_xmit_data_q = list_new(NULL);
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+ p_lcb->completed_packets = 0;
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
return (p_lcb);
}
}
@@ -137,7 +140,7 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb)
memset(&p_lcb->info_timer_entry, 0, sizeof(TIMER_LIST_ENT));
btu_free_timer(&p_lcb->upda_con_timer);
memset(&p_lcb->upda_con_timer, 0, sizeof(TIMER_LIST_ENT));
-
+
/* Release any unfinished L2CAP packet on this link */
if (p_lcb->p_hcit_rcv_acl) {
osi_free(p_lcb->p_hcit_rcv_acl);
@@ -250,6 +253,11 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb)
fixed_queue_free(p_lcb->le_sec_pending_q, NULL);
p_lcb->le_sec_pending_q = NULL;
}
+
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+ p_lcb->completed_packets = 0;
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
}
@@ -1488,7 +1496,7 @@ tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid)
btu_free_quick_timer(&p_ccb->fcrb.ack_timer);
memset(&p_ccb->fcrb.ack_timer, 0, sizeof(TIMER_LIST_ENT));
p_ccb->fcrb.ack_timer.param = (TIMER_PARAM_TYPE)p_ccb;
-
+
btu_free_quick_timer(&p_ccb->fcrb.mon_retrans_timer);
memset(&p_ccb->fcrb.mon_retrans_timer, 0, sizeof(TIMER_LIST_ENT));
p_ccb->fcrb.mon_retrans_timer.param = (TIMER_PARAM_TYPE)p_ccb;
@@ -1511,11 +1519,11 @@ tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid)
p_ccb->max_rx_mtu = L2CAP_MTU_SIZE;
p_ccb->tx_mps = L2CAP_FCR_TX_BUF_SIZE - 32;
- p_ccb->xmit_hold_q = fixed_queue_new(SIZE_MAX);
+ p_ccb->xmit_hold_q = fixed_queue_new(QUEUE_SIZE_MAX);
#if (CLASSIC_BT_INCLUDED == TRUE)
- p_ccb->fcrb.srej_rcv_hold_q = fixed_queue_new(SIZE_MAX);
- p_ccb->fcrb.retrans_q = fixed_queue_new(SIZE_MAX);
- p_ccb->fcrb.waiting_for_ack_q = fixed_queue_new(SIZE_MAX);
+ p_ccb->fcrb.srej_rcv_hold_q = fixed_queue_new(QUEUE_SIZE_MAX);
+ p_ccb->fcrb.retrans_q = fixed_queue_new(QUEUE_SIZE_MAX);
+ p_ccb->fcrb.waiting_for_ack_q = fixed_queue_new(QUEUE_SIZE_MAX);
#endif ///CLASSIC_BT_INCLUDED == TRUE
p_ccb->cong_sent = FALSE;
@@ -3140,6 +3148,35 @@ void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB *p_ccb)
#endif /* BLE_INCLUDED == TRUE */
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function l2cu_find_completed_packets
+**
+** Description Find the completed packets,
+** Then set it to zero
+**
+** Returns The num of handles
+**
+*******************************************************************************/
+UINT8 l2cu_find_completed_packets(UINT16 *handles, UINT16 *num_packets)
+{
+ int xx;
+ UINT8 num = 0;
+ tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
+
+ for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
+ if ((p_lcb->in_use) && (p_lcb->completed_packets > 0)) {
+ *(handles++) = p_lcb->handle;
+ *(num_packets++) = p_lcb->completed_packets;
+ num++;
+ p_lcb->completed_packets = 0;
+ }
+ }
+
+ return num;
+}
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
/*******************************************************************************
** Functions used by both Full and Light Stack
diff --git a/components/bt/bluedroid/stack/rfcomm/port_api.c b/components/bt/bluedroid/stack/rfcomm/port_api.c
index b5e2c569fa..64ca9d7470 100644
--- a/components/bt/bluedroid/stack/rfcomm/port_api.c
+++ b/components/bt/bluedroid/stack/rfcomm/port_api.c
@@ -1459,30 +1459,6 @@ int PORT_WriteDataCO (UINT16 handle, int *p_len, int len, UINT8 *p_data)
length = RFCOMM_DATA_BUF_SIZE -
(UINT16)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
- /* If there are buffers scheduled for transmission check if requested */
- /* data fits into the end of the queue */
- osi_mutex_global_lock();
-
- if (((p_buf = (BT_HDR *)fixed_queue_try_peek_last(p_port->tx.queue)) != NULL)
- && (((int)p_buf->len + available) <= (int)p_port->peer_mtu)
- && (((int)p_buf->len + available) <= (int)length)) {
- memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, available);
- p_port->tx.queue_size += (UINT16)available;
-
- *p_len = available;
- p_buf->len += (UINT16)available;
-
- osi_mutex_global_unlock();
-
- return (PORT_SUCCESS);
- }
-
- osi_mutex_global_unlock();
-
- //int max_read = length < p_port->peer_mtu ? length : p_port->peer_mtu;
-
- //max_read = available < max_read ? available : max_read;
-
while (available) {
/* if we're over buffer high water mark, we're done */
if ((p_port->tx.queue_size > PORT_TX_HIGH_WM)
@@ -1495,20 +1471,24 @@ int PORT_WriteDataCO (UINT16 handle, int *p_len, int len, UINT8 *p_data)
}
/* continue with rfcomm data write */
- p_buf = (BT_HDR *)osi_malloc(RFCOMM_DATA_BUF_SIZE);
+ if (p_port->peer_mtu < length) {
+ length = p_port->peer_mtu;
+ }
+
+ if (available < (int)length) {
+ length = (UINT16)available;
+ }
+
+ UINT16 alloc_size = (UINT16)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD+length);
+ p_buf = (BT_HDR *)osi_malloc(alloc_size);
if (!p_buf) {
+ RFCOMM_TRACE_EVENT ("PORT_WriteDataCO: out of heap.");
break;
}
p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
p_buf->layer_specific = handle;
- if (p_port->peer_mtu < length) {
- length = p_port->peer_mtu;
- }
- if (available < (int)length) {
- length = (UINT16)available;
- }
p_buf->len = length;
p_buf->event = BT_EVT_TO_BTU_SP_DATA;
@@ -1518,7 +1498,7 @@ int PORT_WriteDataCO (UINT16 handle, int *p_len, int len, UINT8 *p_data)
rc = port_write (p_port, p_buf);
- /* If queue went below the threashold need to send flow control */
+ /* If queue went below the threshold need to send flow control */
event |= port_flow_control_user (p_port);
if (rc == PORT_SUCCESS) {
@@ -1531,6 +1511,7 @@ int PORT_WriteDataCO (UINT16 handle, int *p_len, int len, UINT8 *p_data)
*p_len += length;
available -= (int)length;
+ p_data += length;
}
if (!available && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED)) {
event |= PORT_EV_TXEMPTY;
diff --git a/components/bt/bluedroid/stack/rfcomm/port_utils.c b/components/bt/bluedroid/stack/rfcomm/port_utils.c
index a88ae016f8..0da8b3d76b 100644
--- a/components/bt/bluedroid/stack/rfcomm/port_utils.c
+++ b/components/bt/bluedroid/stack/rfcomm/port_utils.c
@@ -128,8 +128,8 @@ void port_set_defaults (tPORT *p_port)
memset (&p_port->rx, 0, sizeof (p_port->rx));
memset (&p_port->tx, 0, sizeof (p_port->tx));
- p_port->tx.queue = fixed_queue_new(SIZE_MAX);
- p_port->rx.queue = fixed_queue_new(SIZE_MAX);
+ p_port->tx.queue = fixed_queue_new(QUEUE_SIZE_MAX);
+ p_port->rx.queue = fixed_queue_new(QUEUE_SIZE_MAX);
}
/*******************************************************************************
diff --git a/components/bt/bluedroid/stack/rfcomm/rfc_utils.c b/components/bt/bluedroid/stack/rfcomm/rfc_utils.c
index 180632c048..8b1e043116 100644
--- a/components/bt/bluedroid/stack/rfcomm/rfc_utils.c
+++ b/components/bt/bluedroid/stack/rfcomm/rfc_utils.c
@@ -175,7 +175,7 @@ tRFC_MCB *rfc_alloc_multiplexer_channel (BD_ADDR bd_addr, BOOLEAN is_initiator)
RFCOMM_TRACE_DEBUG("rfc_alloc_multiplexer_channel:is_initiator:%d, create new p_mcb:%p, index:%d",
is_initiator, &rfc_cb.port.rfc_mcb[j], j);
- p_mcb->cmd_q = fixed_queue_new(SIZE_MAX);
+ p_mcb->cmd_q = fixed_queue_new(QUEUE_SIZE_MAX);
p_mcb->is_initiator = is_initiator;
diff --git a/components/bt/bluedroid/stack/smp/include/p_256_ecc_pp.h b/components/bt/bluedroid/stack/smp/include/p_256_ecc_pp.h
index 029a79ff16..f91d6056b2 100644
--- a/components/bt/bluedroid/stack/smp/include/p_256_ecc_pp.h
+++ b/components/bt/bluedroid/stack/smp/include/p_256_ecc_pp.h
@@ -58,6 +58,8 @@ extern elliptic_curve_t curve_p256;
void ECC_PointMult_Bin_NAF(Point *q, Point *p, DWORD *n, uint32_t keyLength);
+bool ECC_CheckPointIsInElliCur_P256(Point *p);
+
#define ECC_PointMult(q, p, n, keyLength) ECC_PointMult_Bin_NAF(q, p, n, keyLength)
void p_256_init_curve(UINT32 keyLength);
diff --git a/components/bt/bluedroid/stack/smp/p_256_ecc_pp.c b/components/bt/bluedroid/stack/smp/p_256_ecc_pp.c
index 991b6fd757..0f7ab3ec41 100644
--- a/components/bt/bluedroid/stack/smp/p_256_ecc_pp.c
+++ b/components/bt/bluedroid/stack/smp/p_256_ecc_pp.c
@@ -240,4 +240,40 @@ void ECC_PointMult_Bin_NAF(Point *q, Point *p, DWORD *n, uint32_t keyLength)
multiprecision_mersenns_mult_mod(q->y, q->y, q->z, keyLength);
}
+bool ECC_CheckPointIsInElliCur_P256(Point *p)
+{
+ /* y^2 % q */
+ DWORD y_y_q[KEY_LENGTH_DWORDS_P256] = {0x0};
+ /* x^2 % q */
+ DWORD x_x_q[KEY_LENGTH_DWORDS_P256] = {0x0};
+ /* x % q */
+ DWORD x_q[KEY_LENGTH_DWORDS_P256] = {0x0};
+ /* x^2, To prevent overflow, the length of the x square here needs to
+ be expanded to two times the original one. */
+ DWORD x_x[2*KEY_LENGTH_DWORDS_P256] = {0x0};
+ /* y_y_q =(p->y)^2(mod q) */
+ multiprecision_mersenns_squa_mod(y_y_q, p->y, KEY_LENGTH_DWORDS_P256);
+ /* Calculate the value of p->x square, x_x = (p->x)^2 */
+ multiprecision_mult(x_x, p->x, p->x, KEY_LENGTH_DWORDS_P256);
+ /* The function of the elliptic curve is y^2 = x^3 - 3x + b (mod q) ==>
+ y^2 = (x^2 - 3)*x + b (mod q),
+ so we calculate the x^2 - 3 value here */
+ x_x[0] -= 3;
+ /* Using math relations. (a*b) % q = ((a%q)*(b%q)) % q ==>
+ (x^2 - 3)*x = (((x^2 - 3) % q) * x % q) % q */
+ multiprecision_fast_mod_P256(x_x_q, x_x);
+ /* x_x = x_x_q * x_q */
+ multiprecision_mult(x_x, x_x_q, p->x, KEY_LENGTH_DWORDS_P256);
+ /* x_q = x_x % q */
+ multiprecision_fast_mod_P256(x_q, x_x);
+ /* Save the result in x_x_q */
+ multiprecision_add_mod(x_x_q, x_q, curve_p256.b, KEY_LENGTH_DWORDS_P256);
+ /* compare the y_y_q and x_x_q, see if they are on a given elliptic curve. */
+ if (multiprecision_compare(y_y_q, x_x_q, KEY_LENGTH_DWORDS_P256)) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
diff --git a/components/bt/bluedroid/stack/smp/smp_act.c b/components/bt/bluedroid/stack/smp/smp_act.c
index 0b5d50be2e..bf3fe7def6 100644
--- a/components/bt/bluedroid/stack/smp/smp_act.c
+++ b/components/bt/bluedroid/stack/smp/smp_act.c
@@ -22,6 +22,7 @@
#include "btm_int.h"
#include "stack/l2c_api.h"
#include "smp_int.h"
+#include "p_256_ecc_pp.h"
//#include "utils/include/bt_utils.h"
#if SMP_INCLUDED == TRUE
@@ -668,6 +669,12 @@ void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
STREAM_TO_ARRAY(p_cb->peer_publ_key.x, p, BT_OCTET32_LEN);
STREAM_TO_ARRAY(p_cb->peer_publ_key.y, p, BT_OCTET32_LEN);
+ /* In order to prevent the x and y coordinates of the public key from being modified,
+ we need to check whether the x and y coordinates are on the given elliptic curve. */
+ if (!ECC_CheckPointIsInElliCur_P256((Point *)&p_cb->peer_publ_key)) {
+ SMP_TRACE_ERROR("%s, Invalid Public key.", __func__);
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
+ }
p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY;
smp_wait_for_both_public_keys(p_cb, NULL);
@@ -1831,7 +1838,7 @@ void smp_set_local_oob_random_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
void smp_link_encrypted(BD_ADDR bda, UINT8 encr_enable)
{
tSMP_CB *p_cb = &smp_cb;
-
+ tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda);
SMP_TRACE_DEBUG("%s encr_enable=%d\n", __func__, encr_enable);
if (memcmp(&smp_cb.pairing_bda[0], bda, BD_ADDR_LEN) == 0) {
@@ -1842,6 +1849,18 @@ void smp_link_encrypted(BD_ADDR bda, UINT8 encr_enable)
btm_ble_update_sec_key_size(bda, p_cb->loc_enc_size);
}
+ smp_sm_event(&smp_cb, SMP_ENCRYPTED_EVT, &encr_enable);
+ }
+ else if(p_dev_rec && !p_dev_rec->enc_init_by_we){
+
+ /*
+ if enc_init_by_we is false, it means that client initiates encryption before slave calls esp_ble_set_encryption()
+ we need initiate pairing_bda and p_cb->role then encryption, for example iPhones
+ */
+ memcpy(&smp_cb.pairing_bda[0], bda, BD_ADDR_LEN);
+ p_cb->state = SMP_STATE_ENCRYPTION_PENDING;
+ p_cb->role = HCI_ROLE_SLAVE;
+ p_dev_rec->enc_init_by_we = FALSE;
smp_sm_event(&smp_cb, SMP_ENCRYPTED_EVT, &encr_enable);
}
}
diff --git a/components/bt/bt.c b/components/bt/bt.c
index f0640917c0..12ca8e3cfe 100644
--- a/components/bt/bt.c
+++ b/components/bt/bt.c
@@ -61,9 +61,9 @@
/* not for user call, so don't put to include file */
extern void btdm_osi_funcs_register(void *osi_funcs);
extern int btdm_controller_init(uint32_t config_mask, esp_bt_controller_config_t *config_opts);
-extern int btdm_controller_deinit(void);
+extern void btdm_controller_deinit(void);
extern int btdm_controller_enable(esp_bt_mode_t mode);
-extern int btdm_controller_disable(esp_bt_mode_t mode);
+extern void btdm_controller_disable(void);
extern uint8_t btdm_controller_get_mode(void);
extern const char *btdm_controller_get_compile_version(void);
extern void btdm_rf_bb_init(void);
@@ -103,6 +103,14 @@ extern void bredr_sco_datapath_set(uint8_t data_path);
extern char _bss_start_btdm;
extern char _bss_end_btdm;
+extern uint32_t _bt_bss_start;
+extern uint32_t _bt_bss_end;
+extern uint32_t _btdm_bss_start;
+extern uint32_t _btdm_bss_end;
+extern uint32_t _bt_data_start;
+extern uint32_t _bt_data_end;
+extern uint32_t _btdm_data_start;
+extern uint32_t _btdm_data_end;
extern char _data_start_btdm;
extern char _data_end_btdm;
extern uint32_t _data_start_btdm_rom;
@@ -141,6 +149,11 @@ static btdm_dram_available_region_t btdm_dram_available_region[] = {
{ESP_BT_MODE_BTDM, 0x3ffbdb28, 0x3ffc0000},
};
+/* Reserve the full memory region used by Bluetooth Controller,
+ some may be released later at runtime. */
+SOC_RESERVE_MEMORY_REGION(0x3ffb0000, 0x3ffc0000, bt_hardware_shared_mem);
+SOC_RESERVE_MEMORY_REGION(0x3ffae6e0, 0x3ffaff10, rom_bt_data);
+
#if CONFIG_SPIRAM_USE_MALLOC
typedef struct {
QueueHandle_t handle;
@@ -254,12 +267,20 @@ bool IRAM_ATTR btdm_queue_generic_deregister(btdm_queue_item_t *queue)
static void IRAM_ATTR interrupt_disable(void)
{
- portENTER_CRITICAL(&global_int_mux);
+ if (xPortInIsrContext()) {
+ portENTER_CRITICAL_ISR(&global_int_mux);
+ } else {
+ portENTER_CRITICAL(&global_int_mux);
+ }
}
static void IRAM_ATTR interrupt_restore(void)
{
- portEXIT_CRITICAL(&global_int_mux);
+ if (xPortInIsrContext()) {
+ portEXIT_CRITICAL_ISR(&global_int_mux);
+ } else {
+ portEXIT_CRITICAL(&global_int_mux);
+ }
}
static void IRAM_ATTR task_yield_from_isr(void)
@@ -575,9 +596,7 @@ static int IRAM_ATTR rand_wrapper(void)
static uint32_t IRAM_ATTR btdm_lpcycles_2_us(uint32_t cycles)
{
- // Sanity check. The number of lp cycles should not be too high to avoid overflow. Thrs: 100s (for 32kHz freq)
- assert(cycles < 3200000);
-
+ // The number of lp cycles should not lead to overflow. Thrs: 100s (for 32kHz freq)
// clock measurement is conducted
uint64_t us = (uint64_t)btdm_lpcycle_us * cycles;
us = (us + (1 << (btdm_lpcycle_us_frac - 1))) >> btdm_lpcycle_us_frac;
@@ -589,9 +608,7 @@ static uint32_t IRAM_ATTR btdm_lpcycles_2_us(uint32_t cycles)
*/
static uint32_t IRAM_ATTR btdm_us_2_lpcycles(uint32_t us)
{
- // Sanity check: the number of sleep duration(us) should not be too high to avoid overflow. Thrs: 100s
- assert(us < 100000000);
-
+ // The number of sleep duration(us) should not lead to overflow. Thrs: 100s
// Compute the sleep duration in us to low power clock cycles, with calibration result applied
// clock measurement is conducted
uint64_t cycles = ((uint64_t)(us) << btdm_lpcycle_us_frac) / btdm_lpcycle_us;
@@ -604,6 +621,8 @@ static bool IRAM_ATTR btdm_sleep_check_duration(uint32_t *slot_cnt)
if (*slot_cnt < BTDM_MIN_SLEEP_DURATION) {
return false;
}
+ /* wake up 3 slots in advance */
+ *slot_cnt = *slot_cnt -3;
return true;
}
@@ -612,9 +631,6 @@ static void IRAM_ATTR btdm_sleep_enter_wrapper(void)
if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
esp_modem_sleep_enter(MODEM_BLE_MODULE);
esp_modem_sleep_enter(MODEM_CLASSIC_BT_MODULE);
-#ifdef CONFIG_PM_ENABLE
- esp_pm_lock_release(s_pm_lock);
-#endif
} else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
esp_modem_sleep_enter(MODEM_BLE_MODULE);
// pause bluetooth baseband
@@ -625,9 +641,6 @@ static void IRAM_ATTR btdm_sleep_enter_wrapper(void)
static void IRAM_ATTR btdm_sleep_exit_wrapper(void)
{
if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
-#ifdef CONFIG_PM_ENABLE
- esp_pm_lock_acquire(s_pm_lock);
-#endif
esp_modem_sleep_exit(MODEM_BLE_MODULE);
esp_modem_sleep_exit(MODEM_CLASSIC_BT_MODULE);
} else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
@@ -769,17 +782,50 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
continue;
} else {
ESP_LOGD(BTDM_LOG_TAG, "Release DRAM [0x%08x] - [0x%08x]\n", mem_start, mem_end);
- ESP_ERROR_CHECK( heap_caps_add_region(mem_start, mem_end));
+ ESP_ERROR_CHECK(heap_caps_add_region(mem_start, mem_end));
update = true;
}
} else {
mem_end = btdm_dram_available_region[i].end;
ESP_LOGD(BTDM_LOG_TAG, "Release DRAM [0x%08x] - [0x%08x]\n", mem_start, mem_end);
- ESP_ERROR_CHECK( heap_caps_add_region(mem_start, mem_end));
+ ESP_ERROR_CHECK(heap_caps_add_region(mem_start, mem_end));
update = true;
}
}
+ if (mode == ESP_BT_MODE_BTDM) {
+ mem_start = (intptr_t)&_btdm_bss_start;
+ mem_end = (intptr_t)&_btdm_bss_end;
+ ESP_LOGD(BTDM_LOG_TAG, "Release BTDM BSS [0x%08x] - [0x%08x]\n", mem_start, mem_end);
+ ESP_ERROR_CHECK(heap_caps_add_region(mem_start, mem_end));
+ mem_start = (intptr_t)&_btdm_data_start;
+ mem_end = (intptr_t)&_btdm_data_end;
+ ESP_LOGD(BTDM_LOG_TAG, "Release BTDM Data [0x%08x] - [0x%08x]\n", mem_start, mem_end);
+ ESP_ERROR_CHECK(heap_caps_add_region(mem_start, mem_end));
+ }
+ return ESP_OK;
+}
+
+esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
+{
+ int ret;
+ intptr_t mem_start, mem_end;
+
+ ret = esp_bt_controller_mem_release(mode);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+
+ if (mode == ESP_BT_MODE_BTDM) {
+ mem_start = (intptr_t)&_bt_bss_start;
+ mem_end = (intptr_t)&_bt_bss_end;
+ ESP_LOGD(BTDM_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x]\n", mem_start, mem_end);
+ ESP_ERROR_CHECK(heap_caps_add_region(mem_start, mem_end));
+ mem_start = (intptr_t)&_bt_data_start;
+ mem_end = (intptr_t)&_bt_data_end;
+ ESP_LOGD(BTDM_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x]\n", mem_start, mem_end);
+ ESP_ERROR_CHECK(heap_caps_add_region(mem_start, mem_end));
+ }
return ESP_OK;
}
@@ -835,9 +881,9 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = 32 << btdm_lpcycle_us_frac;
+#if CONFIG_BTDM_MODEM_SLEEP_MODE_ORIG
bool select_src_ret = false;
bool set_div_ret = false;
-#if CONFIG_BTDM_MODEM_SLEEP_MODE_ORIG
#if CONFIG_BTDM_LPCLK_SEL_MAIN_XTAL
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL);
set_div_ret = btdm_lpclk_set_div(rtc_clk_xtal_freq_get() * 32 - 1);
@@ -880,9 +926,7 @@ esp_err_t esp_bt_controller_deinit(void)
return ESP_ERR_INVALID_STATE;
}
- if (btdm_controller_deinit() != 0) {
- return ESP_ERR_NO_MEM;
- }
+ btdm_controller_deinit();
periph_module_disable(PERIPH_BT_MODULE);
@@ -923,7 +967,14 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
esp_phy_load_cal_and_init(PHY_BT_MODULE);
- if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
+ if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_NONE) {
+ //Just register to sleep module, make the modem sleep modules check BT sleep status when sleep enter.
+ //Thus, it will prevent WIFI from disabling RF when BT is not in sleep but is using RF.
+ esp_modem_sleep_register(MODEM_BLE_MODULE);
+ esp_modem_sleep_register(MODEM_CLASSIC_BT_MODULE);
+ esp_modem_sleep_exit(MODEM_BLE_MODULE);
+ esp_modem_sleep_exit(MODEM_CLASSIC_BT_MODULE);
+ } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
esp_modem_sleep_register(MODEM_BLE_MODULE);
esp_modem_sleep_register(MODEM_CLASSIC_BT_MODULE);
} else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
@@ -941,13 +992,17 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
ret = btdm_controller_enable(mode);
if (ret) {
- if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
+ if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_NONE
+ || btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
esp_modem_sleep_deregister(MODEM_BLE_MODULE);
esp_modem_sleep_deregister(MODEM_CLASSIC_BT_MODULE);
} else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
esp_modem_sleep_deregister(MODEM_BLE_MODULE);
}
esp_phy_rf_deinit(PHY_BT_MODULE);
+#ifdef CONFIG_PM_ENABLE
+ esp_pm_lock_release(s_pm_lock);
+#endif
return ESP_ERR_INVALID_STATE;
}
@@ -958,8 +1013,6 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
esp_err_t esp_bt_controller_disable(void)
{
- int ret;
-
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
@@ -975,21 +1028,17 @@ esp_err_t esp_bt_controller_disable(void)
}
}
- ret = btdm_controller_disable(btdm_controller_get_mode());
- if (ret < 0) {
- return ESP_ERR_INVALID_STATE;
- }
+ btdm_controller_disable();
- if (ret == ESP_BT_MODE_IDLE) {
- if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
- esp_modem_sleep_deregister(MODEM_BLE_MODULE);
- esp_modem_sleep_deregister(MODEM_CLASSIC_BT_MODULE);
- } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
- esp_modem_sleep_deregister(MODEM_BLE_MODULE);
- }
- esp_phy_rf_deinit(PHY_BT_MODULE);
- btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
+ if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_NONE
+ || btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
+ esp_modem_sleep_deregister(MODEM_BLE_MODULE);
+ esp_modem_sleep_deregister(MODEM_CLASSIC_BT_MODULE);
+ } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
+ esp_modem_sleep_deregister(MODEM_BLE_MODULE);
}
+ esp_phy_rf_deinit(PHY_BT_MODULE);
+ btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_release(s_pm_lock);
diff --git a/components/bt/include/esp_bt.h b/components/bt/include/esp_bt.h
index 1fda81dad0..6ab606ff62 100644
--- a/components/bt/include/esp_bt.h
+++ b/components/bt/include/esp_bt.h
@@ -46,7 +46,7 @@ typedef struct {
/* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE,
the adv packet will be discarded until the memory is restored. */
#define SCAN_SEND_ADV_RESERVED_SIZE 1000
-/* open controller log debug when adv lost */
+/* enable controller log debug when adv lost */
#define CONTROLLER_ADV_LOST_DEBUG_BIT (0<<0)
#ifdef CONFIG_BT_HCI_UART_NO
@@ -132,7 +132,7 @@ typedef enum {
* ESP_BLE_PWR_TYPE_SCAN : for scan.
* ESP_BLE_PWR_TYPE_DEFAULT : if each connection's TX power is not set, it will use this default value.
* if neither in scan mode nor in adv mode, it will use this default value.
- * If none of power type is set, system will use ESP_PWR_LVL_P1 as default for ADV/SCAN/CONN0-9.
+ * If none of power type is set, system will use ESP_PWR_LVL_P3 as default for ADV/SCAN/CONN0-9.
*/
typedef enum {
ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, /*!< For connection handle 0 */
@@ -154,14 +154,22 @@ typedef enum {
* @brief Bluetooth TX power level(index), it's just a index corresponding to power(dbm).
*/
typedef enum {
- ESP_PWR_LVL_N14 = 0, /*!< Corresponding to -14dbm */
- ESP_PWR_LVL_N11 = 1, /*!< Corresponding to -11dbm */
- ESP_PWR_LVL_N8 = 2, /*!< Corresponding to -8dbm */
- ESP_PWR_LVL_N5 = 3, /*!< Corresponding to -5dbm */
- ESP_PWR_LVL_N2 = 4, /*!< Corresponding to -2dbm */
- ESP_PWR_LVL_P1 = 5, /*!< Corresponding to 1dbm */
- ESP_PWR_LVL_P4 = 6, /*!< Corresponding to 4dbm */
- ESP_PWR_LVL_P7 = 7, /*!< Corresponding to 7dbm */
+ ESP_PWR_LVL_N12 = 0, /*!< Corresponding to -12dbm */
+ ESP_PWR_LVL_N9 = 1, /*!< Corresponding to -9dbm */
+ ESP_PWR_LVL_N6 = 2, /*!< Corresponding to -6dbm */
+ ESP_PWR_LVL_N3 = 3, /*!< Corresponding to -3dbm */
+ ESP_PWR_LVL_N0 = 4, /*!< Corresponding to 0dbm */
+ ESP_PWR_LVL_P3 = 5, /*!< Corresponding to +3dbm */
+ ESP_PWR_LVL_P6 = 6, /*!< Corresponding to +6dbm */
+ ESP_PWR_LVL_P9 = 7, /*!< Corresponding to +9dbm */
+ ESP_PWR_LVL_N14 = ESP_PWR_LVL_N12, /*!< Backward compatibility! Setting to -14dbm will actually result to -12dbm */
+ ESP_PWR_LVL_N11 = ESP_PWR_LVL_N9, /*!< Backward compatibility! Setting to -11dbm will actually result to -9dbm */
+ ESP_PWR_LVL_N8 = ESP_PWR_LVL_N6, /*!< Backward compatibility! Setting to -8dbm will actually result to -6dbm */
+ ESP_PWR_LVL_N5 = ESP_PWR_LVL_N3, /*!< Backward compatibility! Setting to -5dbm will actually result to -3dbm */
+ ESP_PWR_LVL_N2 = ESP_PWR_LVL_N0, /*!< Backward compatibility! Setting to -2dbm will actually result to 0dbm */
+ ESP_PWR_LVL_P1 = ESP_PWR_LVL_P3, /*!< Backward compatibility! Setting to +1dbm will actually result to +3dbm */
+ ESP_PWR_LVL_P4 = ESP_PWR_LVL_P6, /*!< Backward compatibility! Setting to +4dbm will actually result to +6dbm */
+ ESP_PWR_LVL_P7 = ESP_PWR_LVL_P9, /*!< Backward compatibility! Setting to +7dbm will actually result to +9dbm */
} esp_power_level_t;
/**
@@ -198,7 +206,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type);
* For example, if you want BR/EDR use the new TX power to do inquire, you should call
* this function before inquire. Another word, If call this function when BR/EDR is in inquire(ING),
* please do inquire again after call this function.
- * Default minimum power level is ESP_PWR_LVL_N2, and maximum power level is ESP_PWR_LVL_P1.
+ * Default minimum power level is ESP_PWR_LVL_N0, and maximum power level is ESP_PWR_LVL_P3.
* @param min_power_level: The minimum power level
* @param max_power_level: The maximum power level
* @return ESP_OK - success, other - failed
@@ -290,33 +298,62 @@ void esp_vhci_host_send_packet(uint8_t *data, uint16_t len);
void esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback);
/** @brief esp_bt_controller_mem_release
- * release the memory by mode, if never use the bluetooth mode
- * it can release the .bbs, .data and other section to heap.
- * The total size is about 70k bytes.
+ * release the controller memory as per the mode
+ *
+ * This function releases the BSS, data and other sections of the controller to heap. The total size is about 70k bytes.
*
* esp_bt_controller_mem_release(mode) should be called only before esp_bt_controller_init()
* or after esp_bt_controller_deinit().
*
- * Note that once BT controller memory is released, the process cannot be reversed. It means you can not use the bluetooth
+ * Note that once BT controller memory is released, the process cannot be reversed. It means you cannot use the bluetooth
* mode which you have released by this function.
*
* If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled)
* then do not call this function.
*
* If the app calls esp_bt_controller_enable(ESP_BT_MODE_BLE) to use BLE only then it is safe to call
- * esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialisation time to free unused BT Classic memory.
+ * esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialization time to free unused BT Classic memory.
*
- * If user never use bluetooth controller, could call esp_bt_controller_mem_release(ESP_BT_MODE_BTDM)
- * before esp_bt_controller_init or after esp_bt_controller_deinit.
- *
- * For example, user only use bluetooth to config SSID and PASSWORD of WIFI, after config, will never use bluetooth.
- * Then, could call esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) after esp_bt_controller_deinit.
+ * If the mode is ESP_BT_MODE_BTDM, then it may be useful to call API esp_bt_mem_release(ESP_BT_MODE_BTDM) instead,
+ * which internally calls esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) and additionally releases the BSS and data
+ * consumed by the BT/BLE host stack to heap. For more details about usage please refer to the documentation of
+ * esp_bt_mem_release() function
*
* @param mode : the mode want to release memory
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode);
+/** @brief esp_bt_mem_release
+ * release controller memory and BSS and data section of the BT/BLE host stack as per the mode
+ *
+ * This function first releases controller memory by internally calling esp_bt_controller_mem_release().
+ * Additionally, if the mode is set to ESP_BT_MODE_BTDM, it also releases the BSS and data consumed by the BT/BLE host stack to heap
+ *
+ * Note that once BT memory is released, the process cannot be reversed. It means you cannot use the bluetooth
+ * mode which you have released by this function.
+ *
+ * If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled)
+ * then do not call this function.
+ *
+ * If you never intend to use bluetooth in a current boot-up cycle, you can call esp_bt_mem_release(ESP_BT_MODE_BTDM)
+ * before esp_bt_controller_init or after esp_bt_controller_deinit.
+ *
+ * For example, if a user only uses bluetooth for setting the WiFi configuration, and does not use bluetooth in the rest of the product operation".
+ * In such cases, after receiving the WiFi configuration, you can disable/deinit bluetooth and release its memory.
+ * Below is the sequence of APIs to be called for such scenarios:
+ *
+ * esp_bluedroid_disable();
+ * esp_bluedroid_deinit();
+ * esp_bt_controller_disable();
+ * esp_bt_controller_deinit();
+ * esp_bt_mem_release(ESP_BT_MODE_BTDM);
+ *
+ * @param mode : the mode whose memory is to be released
+ * @return ESP_OK - success, other - failed
+ */
+esp_err_t esp_bt_mem_release(esp_bt_mode_t mode);
+
/**
* @brief enable bluetooth to enter modem sleep
*
diff --git a/components/bt/lib b/components/bt/lib
index cfd66eb9b7..d3c834d661 160000
--- a/components/bt/lib
+++ b/components/bt/lib
@@ -1 +1 @@
-Subproject commit cfd66eb9b77d6d98dae79ba505378f438b2ef095
+Subproject commit d3c834d66153b1acd6b4e5e744a66aaa55ae5c40
diff --git a/components/bt/test/component.mk b/components/bt/test/component.mk
new file mode 100644
index 0000000000..5dd172bdb7
--- /dev/null
+++ b/components/bt/test/component.mk
@@ -0,0 +1,5 @@
+#
+#Component Makefile
+#
+
+COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
diff --git a/components/bt/test/test_smp.c b/components/bt/test/test_smp.c
new file mode 100644
index 0000000000..8758f9ccf4
--- /dev/null
+++ b/components/bt/test/test_smp.c
@@ -0,0 +1,107 @@
+/*
+ Tests for the BLE SMP implementation
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/semphr.h"
+#include "freertos/queue.h"
+#include "freertos/xtensa_api.h"
+#include "unity.h"
+#include "esp_heap_caps.h"
+#include "esp_log.h"
+#include "freertos/ringbuf.h"
+#include "esp_system.h"
+#include "nvs_flash.h"
+
+#include "esp_bt.h"
+#include "esp_bt_main.h"
+#include "esp_bt_device.h"
+#include "esp_gap_ble_api.h"
+
+#define TAG "ble_smp_test"
+
+#define KEY_LENGTH_DWORDS_P256 8
+
+typedef unsigned long DWORD;
+typedef uint32_t UINT32;
+
+typedef struct {
+DWORD x[KEY_LENGTH_DWORDS_P256];
+ DWORD y[KEY_LENGTH_DWORDS_P256];
+ DWORD z[KEY_LENGTH_DWORDS_P256];
+} Point;
+
+typedef struct {
+ // curve's coefficients
+ DWORD a[KEY_LENGTH_DWORDS_P256];
+ DWORD b[KEY_LENGTH_DWORDS_P256];
+
+ //whether a is -3
+ int a_minus3;
+
+ // prime modulus
+ DWORD p[KEY_LENGTH_DWORDS_P256];
+
+ // Omega, p = 2^m -omega
+ DWORD omega[KEY_LENGTH_DWORDS_P256];
+
+ // base point, a point on E of order r
+ Point G;
+
+} elliptic_curve_t;
+
+extern void ECC_PointMult_Bin_NAF(Point *q, Point *p, DWORD *n, uint32_t keyLength);
+extern bool ECC_CheckPointIsInElliCur_P256(Point *p);
+extern void p_256_init_curve(UINT32 keyLength);
+extern elliptic_curve_t curve_p256;
+
+static void bt_rand(void *buf, size_t len)
+{
+ if (!len) {
+ return;
+ }
+ // Reset the buf value to the fixed value.
+ memset(buf, 0x55, len);
+
+ for (int i = 0; i < (int)(len / sizeof(uint32_t)); i++) {
+ uint32_t rand = esp_random();
+ memcpy(buf + i*sizeof(uint32_t), &rand, sizeof(uint32_t));
+ }
+
+ return;
+}
+
+TEST_CASE("ble_smp_public_key_check", "[ble_smp]")
+{
+ /* We wait init finish 200ms here */
+ vTaskDelay(200 / portTICK_PERIOD_MS);
+ Point public_key;
+ DWORD private_key[KEY_LENGTH_DWORDS_P256] = {[0 ... (KEY_LENGTH_DWORDS_P256 - 1)] = 0x12345678};
+ p_256_init_curve(KEY_LENGTH_DWORDS_P256);
+ ECC_PointMult_Bin_NAF(&public_key, &(curve_p256.G), private_key, KEY_LENGTH_DWORDS_P256);
+ /* Check Is the public key generated by the system on the given elliptic curve */
+ TEST_ASSERT(ECC_CheckPointIsInElliCur_P256(&public_key));
+ /* We simulate the attacker and set the y coordinate of the public key to 0. */
+ for (int i = 0; i < KEY_LENGTH_DWORDS_P256; i++) {
+ public_key.y[i] = 0x0;
+ }
+ /* At this point the public key should not be on the given elliptic curve. */
+ TEST_ASSERT(!ECC_CheckPointIsInElliCur_P256(&public_key));
+ /* Test whether the G point on the protocol is on a given elliptic curve */
+ TEST_ASSERT(ECC_CheckPointIsInElliCur_P256(&(curve_p256.G)));
+ /* test 100 times when the private key is generated by the random number. */
+ for (int j = 0; j < 100; j++) {
+ bt_rand(private_key, sizeof(DWORD)*KEY_LENGTH_DWORDS_P256);
+ ECC_PointMult_Bin_NAF(&public_key, &(curve_p256.G), private_key, KEY_LENGTH_DWORDS_P256);
+ /* Check Is the public key generated by the system on the given elliptic curve */
+ TEST_ASSERT(ECC_CheckPointIsInElliCur_P256(&public_key));
+ }
+}
diff --git a/components/coap/CMakeLists.txt b/components/coap/CMakeLists.txt
index faba933094..da064b19a0 100644
--- a/components/coap/CMakeLists.txt
+++ b/components/coap/CMakeLists.txt
@@ -28,3 +28,14 @@ register_component()
# TODO: find a way to move this to a port header
target_compile_definitions(coap PUBLIC WITH_POSIX)
+set_source_files_properties(
+ libcoap/src/debug.c
+ libcoap/src/pdu.c
+ PROPERTIES COMPILE_FLAGS
+ -Wno-write-strings)
+
+# Temporary suppress "fallthrough" warnings until they are fixed in libcoap repo
+set_source_files_properties(
+ libcoap/src/option.c
+ PROPERTIES COMPILE_FLAGS
+ -Wno-implicit-fallthrough)
diff --git a/components/coap/component.mk b/components/coap/component.mk
index 012188d7ab..4b3d56f567 100644
--- a/components/coap/component.mk
+++ b/components/coap/component.mk
@@ -12,3 +12,5 @@ COMPONENT_SUBMODULES += libcoap
libcoap/src/debug.o: CFLAGS += -Wno-write-strings
libcoap/src/pdu.o: CFLAGS += -Wno-write-strings
+# Temporary suppress "fallthrough" warnings until they are fixed in libcoap repo
+libcoap/src/option.o: CFLAGS += -Wno-implicit-fallthrough
diff --git a/components/coap/port/coap_io_socket.c b/components/coap/port/coap_io_socket.c
index eec8cc1319..4c3f85b458 100644
--- a/components/coap/port/coap_io_socket.c
+++ b/components/coap/port/coap_io_socket.c
@@ -374,8 +374,8 @@ coap_network_read(coap_endpoint_t *ep, coap_packet_t **packet) {
}
/* local interface for IPv4 */
- (*packet)->src.size = sizeof((*packet)->src.addr);
- memcpy(&(*packet)->src.addr.sa, &soc_srcipaddr, (*packet)->src.size);
+ (*packet)->src.size = sizeof((*packet)->src.addr.sa);
+ memcpy(&((*packet)->src.addr.sa), &soc_srcipaddr, (*packet)->src.size);
if (len > coap_get_max_packetlength(*packet)) {
/* FIXME: we might want to send back a response */
diff --git a/components/console/argtable3/argtable3.c b/components/console/argtable3/argtable3.c
index 3fdda9068d..43464d396e 100644
--- a/components/console/argtable3/argtable3.c
+++ b/components/console/argtable3/argtable3.c
@@ -30,6 +30,8 @@
#include "argtable3.h"
+#pragma GCC diagnostic ignored "-Wclobbered"
+
/*******************************************************************************
* This file is part of the argtable3 library.
*
@@ -3071,6 +3073,7 @@ static int trex_charnode(TRex *exp,TRexBool isclass)
exp->_p++;
return node;
} //else default
+ /* falls through */
default:
t = *exp->_p; exp->_p++;
return trex_newnode(exp,t);
diff --git a/components/console/commands.c b/components/console/commands.c
index b1f6bda96e..7d7232869b 100644
--- a/components/console/commands.c
+++ b/components/console/commands.c
@@ -104,7 +104,8 @@ esp_err_t esp_console_cmd_register(const esp_console_cmd_t *cmd)
/* Prepend a space before the hint. It separates command name and
* the hint. arg_print_syntax below adds this space as well.
*/
- asprintf(&item->hint, " %s", cmd->hint);
+ int unused __attribute__((unused));
+ unused = asprintf(&item->hint, " %s", cmd->hint);
} else if (cmd->argtable) {
/* Generate hint based on cmd->argtable */
char *buf = NULL;
diff --git a/components/cxx/component.mk b/components/cxx/component.mk
index 00e05e0db2..7d819675a8 100644
--- a/components/cxx/component.mk
+++ b/components/cxx/component.mk
@@ -9,3 +9,4 @@ ifndef CONFIG_CXX_EXCEPTIONS
COMPONENT_ADD_LDFLAGS += -u __cxx_fatal_exception
endif
+COMPONENT_ADD_INCLUDEDIRS =
diff --git a/components/cxx/cxx_exception_stubs.cpp b/components/cxx/cxx_exception_stubs.cpp
index 3f7632c6d5..b67bc2ad34 100644
--- a/components/cxx/cxx_exception_stubs.cpp
+++ b/components/cxx/cxx_exception_stubs.cpp
@@ -13,12 +13,23 @@ extern "C" void __cxx_fatal_exception(void)
abort();
}
+extern "C" bool __cxx_fatal_exception_bool(void)
+{
+ __cxx_fatal_exception();
+ return false;
+}
+
extern "C" void __cxx_fatal_exception_message(const char *msg)
{
printf("%s%s\n", FATAL_EXCEPTION, msg);
abort();
}
+extern "C" void __cxx_fatal_exception_message_va(const char *msg, ...)
+{
+ __cxx_fatal_exception_message(msg);
+}
+
extern "C" void __cxx_fatal_exception_int(int i)
{
printf("%s (%d)\n", FATAL_EXCEPTION, i);
@@ -43,7 +54,7 @@ void std::__throw_length_error(const char*) __attribute__((alias("__cxx_fatal_ex
void std::__throw_out_of_range(const char*) __attribute__((alias("__cxx_fatal_exception_message")));
-void std::__throw_out_of_range_fmt(const char*, ...) __attribute__((alias("__cxx_fatal_exception_message")));
+void std::__throw_out_of_range_fmt(const char*, ...) __attribute__((alias("__cxx_fatal_exception_message_va")));
void std::__throw_runtime_error(const char*) __attribute__((alias("__cxx_fatal_exception_message")));
@@ -84,6 +95,6 @@ extern "C" void __cxa_rethrow(void) __attribute__((alias("__cxx_fatal_exception"
extern "C" void __cxa_throw(void) __attribute__((alias("__cxx_fatal_exception")));
extern "C" void __cxa_call_terminate(void) __attribute__((alias("__cxx_fatal_exception")));
-bool std::uncaught_exception() __attribute__((alias("__cxx_fatal_exception")));
+bool std::uncaught_exception() __attribute__((alias("__cxx_fatal_exception_bool")));
#endif // CONFIG_CXX_EXCEPTIONS
diff --git a/components/cxx/cxx_guards.cpp b/components/cxx/cxx_guards.cpp
index 288ff3ea03..48819a7ab5 100644
--- a/components/cxx/cxx_guards.cpp
+++ b/components/cxx/cxx_guards.cpp
@@ -33,6 +33,10 @@ static size_t s_static_init_waiting_count = 0; //!< number of tasks
static size_t s_static_init_max_waiting_count = 0; //!< maximum ever value of the above; can be inspected using GDB for debugging purposes
#endif
+extern "C" int __cxa_guard_acquire(__guard* pg);
+extern "C" void __cxa_guard_release(__guard* pg);
+extern "C" void __cxa_guard_abort(__guard* pg);
+extern "C" void __cxa_guard_dummy();
/**
* Layout of the guard object (defined by the ABI).
diff --git a/components/driver/Kconfig b/components/driver/Kconfig
index a327a4e867..bff45a46bf 100644
--- a/components/driver/Kconfig
+++ b/components/driver/Kconfig
@@ -1,4 +1,4 @@
-#menu "Driver configurations"
+menu "Driver configurations"
menu "ADC configuration"
@@ -20,5 +20,30 @@ config ADC2_DISABLE_DAC
endmenu # ADC Configuration
-#endmenu # Driver configurations
+menu "SPI master configuration"
+config SPI_MASTER_IN_IRAM
+ bool "Place transmitting functions of SPI master into IRAM"
+ default n
+ select SPI_MASTER_ISR_IN_IRAM
+ help
+ Normally only the ISR of SPI master is placed in the IRAM, so that it
+ can work without the flash when interrupt is triggered.
+ For other functions, there's some possibility that the flash cache
+ miss when running inside and out of SPI functions, which may increase
+ the interval of SPI transactions.
+ Enable this to put ``queue_trans``, ``get_trans_result`` and
+ ``transmit`` functions into the IRAM to avoid possible cache miss.
+
+ During unit test, this is enabled to measure the ideal case of api.
+
+config SPI_MASTER_ISR_IN_IRAM
+ bool "Place SPI master ISR function into IRAM"
+ default y
+ help
+ Place the SPI master ISR in to IRAM to avoid possibly cache miss, or
+ being disabled during flash writing access.
+
+endmenu # SPI Master Configuration
+
+endmenu # Driver configurations
diff --git a/components/driver/can.c b/components/driver/can.c
new file mode 100644
index 0000000000..139d8a49a7
--- /dev/null
+++ b/components/driver/can.c
@@ -0,0 +1,937 @@
+// Copyright 2015-2018 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.
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/portmacro.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "freertos/semphr.h"
+#include "esp_types.h"
+#include "esp_log.h"
+#include "esp_intr_alloc.h"
+#include "soc/dport_reg.h"
+#include "soc/can_struct.h"
+#include "driver/gpio.h"
+#include "driver/periph_ctrl.h"
+#include "driver/can.h"
+
+/* ---------------------------- Definitions --------------------------------- */
+//Internal Macros
+#define CAN_CHECK(cond, ret_val) ({ \
+ if (!(cond)) { \
+ return (ret_val); \
+ } \
+})
+#define CAN_CHECK_FROM_CRIT(cond, ret_val) ({ \
+ if (!(cond)) { \
+ CAN_EXIT_CRITICAL(); \
+ return ret_val; \
+ } \
+})
+#define CAN_SET_FLAG(var, mask) ((var) |= (mask))
+#define CAN_RESET_FLAG(var, mask) ((var) &= ~(mask))
+#define CAN_TAG "CAN"
+
+//Driver default config/values
+#define DRIVER_DEFAULT_EWL 96 //Default Error Warning Limit value
+#define DRIVER_DEFAULT_TEC 0 //TX Error Counter starting value
+#define DRIVER_DEFAULT_REC 0 //RX Error Counter starting value
+#define DRIVER_DEFAULT_CLKOUT_DIV 14 //APB CLK divided by two
+#define DRIVER_DEFAULT_INTERRUPTS 0xE7 //Exclude data overrun
+#define DRIVER_DEFAULT_ERR_PASS_CNT 128 //Error counter threshold for error passive
+
+//Command Bit Masks
+#define CMD_TX_REQ 0x01 //Transmission Request
+#define CMD_ABORT_TX 0x02 //Abort Transmission
+#define CMD_RELEASE_RX_BUFF 0x04 //Release Receive Buffer
+#define CMD_CLR_DATA_OVRN 0x08 //Clear Data Overrun
+#define CMD_SELF_RX_REQ 0x10 //Self Reception Request
+#define CMD_TX_SINGLE_SHOT 0x03 //Single Shot Transmission
+#define CMD_SELF_RX_SINGLE_SHOT 0x12 //Single Shot Self Reception
+
+//Control flags
+#define CTRL_FLAG_STOPPED 0x001 //CAN peripheral in stopped state
+#define CTRL_FLAG_RECOVERING 0x002 //Bus is undergoing bus recovery
+#define CTRL_FLAG_ERR_WARN 0x004 //TEC or REC is >= error warning limit
+#define CTRL_FLAG_ERR_PASSIVE 0x008 //TEC or REC is >= 128
+#define CTRL_FLAG_BUS_OFF 0x010 //Bus-off due to TEC >= 256
+#define CTRL_FLAG_TX_BUFF_OCCUPIED 0x020 //Transmit buffer is occupied
+#define CTRL_FLAG_SELF_TEST 0x040 //Configured to Self Test Mode
+#define CTRL_FLAG_LISTEN_ONLY 0x080 //Configured to Listen Only Mode
+
+//Constants use for frame formatting and parsing
+#define FRAME_MAX_LEN 13 //EFF with 8 bytes of data
+#define FRAME_MAX_DATA_LEN 8 //Max data bytes allowed in CAN2.0
+#define FRAME_EXTD_ID_LEN 4 //EFF ID requires 4 bytes (29bit)
+#define FRAME_STD_ID_LEN 2 //SFF ID requires 2 bytes (11bit)
+#define FRAME_INFO_LEN 1 //Frame info requires 1 byte
+
+#define ALERT_LOG_LEVEL_WARNING CAN_ALERT_ARB_LOST //Alerts above and including this level use ESP_LOGW
+#define ALERT_LOG_LEVEL_ERROR CAN_ALERT_TX_FAILED //Alerts above and including this level use ESP_LOGE
+
+/* ------------------ Typedefs, structures, and variables ------------------- */
+
+/* Formatted frame structure has identical layout as TX/RX buffer registers.
+ This allows for direct copy to/from 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. */
+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[FRAME_STD_ID_LEN]; //11 bit standard frame identifier
+ uint8_t data[FRAME_MAX_DATA_LEN]; //Data bytes (0 to 8)
+ uint8_t reserved8[2];
+ } standard;
+ struct {
+ uint8_t id[FRAME_EXTD_ID_LEN]; //29 bit extended frame identifier
+ uint8_t data[FRAME_MAX_DATA_LEN]; //Data bytes (0 to 8)
+ } extended;
+ };
+ };
+ uint8_t bytes[FRAME_MAX_LEN];
+} can_frame_t;
+
+//Control structure for CAN driver
+typedef struct {
+ //Control and status members
+ uint32_t control_flags;
+ uint32_t rx_missed_count;
+ uint32_t tx_failed_count;
+ uint32_t arb_lost_count;
+ uint32_t bus_error_count;
+ intr_handle_t isr_handle;
+ //TX and RX
+ QueueHandle_t tx_queue;
+ QueueHandle_t rx_queue;
+ int tx_msg_count;
+ int rx_msg_count;
+ //Alerts
+ SemaphoreHandle_t alert_semphr;
+ uint32_t alerts_enabled;
+ uint32_t alerts_triggered;
+} can_obj_t;
+
+static can_obj_t *p_can_obj = NULL;
+static portMUX_TYPE can_spinlock = portMUX_INITIALIZER_UNLOCKED;
+#define CAN_ENTER_CRITICAL() portENTER_CRITICAL(&can_spinlock)
+#define CAN_EXIT_CRITICAL() portEXIT_CRITICAL(&can_spinlock)
+
+/* ------------------- Configuration Register Functions---------------------- */
+
+static inline esp_err_t can_enter_reset_mode()
+{
+ /* Enter reset mode (required to write to configuration registers). Reset mode
+ also prevents all CAN activity on the current module and is automatically
+ set upon entering a BUS-OFF condition. */
+ CAN.mode_reg.reset = 1; //Set reset mode bit
+ CAN_CHECK(CAN.mode_reg.reset == 1, ESP_ERR_INVALID_STATE); //Check bit was set
+ return ESP_OK;
+}
+
+static inline esp_err_t can_exit_reset_mode()
+{
+ /* Exiting reset mode will return the CAN module to operating mode. Reset mode
+ must also be exited in order to trigger BUS-OFF recovery sequence. */
+ CAN.mode_reg.reset = 0; //Exit reset mode
+ CAN_CHECK(CAN.mode_reg.reset == 0, ESP_ERR_INVALID_STATE); //Check bit was reset
+ return ESP_OK;
+}
+
+static inline void can_config_pelican()
+{
+ //Use PeliCAN address layout. Exposes extra registers
+ CAN.clock_divider_reg.can_mode = 1;
+}
+
+static inline void can_config_mode(can_mode_t mode)
+{
+ //Configure CAN mode of operation
+ can_mode_reg_t mode_reg;
+ mode_reg.val = CAN.mode_reg.val; //Get current value of mode register
+ if (mode == CAN_MODE_NO_ACK) {
+ mode_reg.self_test = 1;
+ mode_reg.listen_only = 0;
+ } else if (mode == CAN_MODE_LISTEN_ONLY) {
+ mode_reg.self_test = 0;
+ mode_reg.listen_only = 1;
+ } else {
+ //Default to normal operating mode
+ mode_reg.self_test = 0;
+ mode_reg.listen_only = 0;
+ }
+ CAN.mode_reg.val = mode_reg.val; //Write back modified value to register
+}
+
+static inline void can_config_interrupts(uint32_t interrupts)
+{
+ //Enable interrupt sources
+ CAN.interrupt_enable_reg.val = interrupts;
+}
+
+static inline void can_config_bus_timing(uint32_t brp, uint32_t sjw, uint32_t tseg_1, uint32_t tseg_2, bool triple_sampling)
+{
+ /* Configure bus/bit timing of CAN peripheral.
+ - BRP (even from 2 to 128) divide APB to CAN system clock (T_scl)
+ - SJW (1 to 4) is number of T_scl to shorten/lengthen for bit synchronization
+ - TSEG_1 (1 to 16) is number of T_scl in a bit time before sample point
+ - TSEG_2 (1 to 8) is number of T_scl in a bit time after sample point
+ - triple_sampling will cause each bit time to be sampled 3 times*/
+ can_bus_tim_0_reg_t timing_reg_0;
+ can_bus_tim_1_reg_t timing_reg_1;
+ timing_reg_0.baud_rate_prescaler = (brp / 2) - 1;
+ timing_reg_0.sync_jump_width = sjw - 1;
+ timing_reg_1.time_seg_1 = tseg_1 - 1;
+ timing_reg_1.time_seg_2 = tseg_2 - 1;
+ timing_reg_1.sampling = triple_sampling;
+ CAN.bus_timing_0_reg.val = timing_reg_0.val;
+ CAN.bus_timing_1_reg.val = timing_reg_1.val;
+}
+
+static inline void can_config_error(int err_warn_lim, int rx_err_cnt, int tx_err_cnt)
+{
+ /* Set error warning limit, RX error counter, and TX error counter. Note that
+ forcibly setting RX/TX error counters will incur the expected status changes
+ and interrupts as soon as reset mode exits. */
+ if (err_warn_lim >= 0 && err_warn_lim <= UINT8_MAX) {
+ //Defaults to 96 after hardware reset.
+ CAN.error_warning_limit_reg.byte = err_warn_lim;
+ }
+ if (rx_err_cnt >= 0 && rx_err_cnt <= UINT8_MAX) {
+ //Defaults to 0 after hardware reset.
+ CAN.rx_error_counter_reg.byte = rx_err_cnt;
+ }
+ if (tx_err_cnt >= 0 && tx_err_cnt <= UINT8_MAX) {
+ //Defaults to 0 after hardware reset, and 127 after BUS-OFF event
+ CAN.tx_error_counter_reg.byte = tx_err_cnt;
+ }
+}
+
+static inline void can_config_acceptance_filter(uint32_t code, uint32_t mask, bool single_filter)
+{
+ //Set filter mode
+ CAN.mode_reg.acceptance_filter = (single_filter) ? 1 : 0;
+ //Swap code and mask to match big endian registers
+ uint32_t code_swapped = __builtin_bswap32(code);
+ uint32_t mask_swapped = __builtin_bswap32(mask);
+ for (int i = 0; i < 4; i++) {
+ CAN.acceptance_filter.code_reg[i].byte = ((code_swapped >> (i * 8)) & 0xFF);
+ CAN.acceptance_filter.mask_reg[i].byte = ((mask_swapped >> (i * 8)) & 0xFF);
+ }
+}
+
+static inline void can_config_clk_out(uint32_t divider)
+{
+ /* Configure CLKOUT. CLKOUT is a pre-scaled version of APB CLK. Divider can be
+ 1, or any even number from 2 to 14. Set to out of range value (0) to disable
+ CLKOUT. */
+ can_clk_div_reg_t clock_divider_reg;
+ clock_divider_reg.val = CAN.clock_divider_reg.val;
+ if (divider >= 2 && divider <= 14) {
+ clock_divider_reg.clock_off = 0;
+ clock_divider_reg.clock_divider = (divider / 2) - 1;
+ } else if (divider == 1) {
+ clock_divider_reg.clock_off = 0;
+ clock_divider_reg.clock_divider = 7;
+ } else {
+ clock_divider_reg.clock_off = 1;
+ clock_divider_reg.clock_divider = 0;
+ }
+ CAN.clock_divider_reg.val = clock_divider_reg.val;
+}
+
+/* ---------------------- Runtime Register Functions------------------------- */
+
+static inline void can_set_command(uint8_t commands)
+{
+ CAN.command_reg.val = commands;
+}
+
+static void can_set_tx_buffer_and_transmit(can_frame_t *frame)
+{
+ //Copy frame structure into TX buffer registers
+ for (int i = 0; i < FRAME_MAX_LEN; i++) {
+ CAN.tx_rx_buffer[i].val = frame->bytes[i];
+ }
+
+ //Set correct transmit command
+ uint8_t command;
+ if (frame->self_reception) {
+ command = (frame->single_shot) ? CMD_SELF_RX_SINGLE_SHOT : CMD_SELF_RX_REQ;
+ } else {
+ command = (frame->single_shot) ? CMD_TX_SINGLE_SHOT : CMD_TX_REQ;
+ }
+ can_set_command(command);
+}
+
+static inline uint32_t can_get_status()
+{
+ return CAN.status_reg.val;
+}
+
+static inline uint32_t can_get_interrupt_reason()
+{
+ return CAN.interrupt_reg.val;
+}
+
+static inline uint32_t can_get_arbitration_lost_capture()
+{
+ return CAN.arbitration_lost_captue_reg.val;
+ //Todo: ALC read only to re-arm arb lost interrupt. Add function to decode ALC
+}
+
+static inline uint32_t can_get_error_code_capture()
+{
+ return CAN.error_code_capture_reg.val;
+ //Todo: ECC read only to re-arm bus error interrupt. Add function to decode ECC
+}
+
+static inline void can_get_error_counters(uint32_t *tx_error_cnt, uint32_t *rx_error_cnt)
+{
+ if (tx_error_cnt != NULL) {
+ *tx_error_cnt = CAN.tx_error_counter_reg.byte;
+ }
+ if (rx_error_cnt != NULL) {
+ *rx_error_cnt = CAN.rx_error_counter_reg.byte;
+ }
+}
+
+static inline void can_get_rx_buffer_and_clear(can_frame_t *frame)
+{
+ //Copy RX buffer registers into frame structure
+ for (int i = 0; i < FRAME_MAX_LEN; i++) {
+ frame->bytes[i] = CAN.tx_rx_buffer[i].val;
+ }
+ //Clear RX buffer
+ can_set_command(CMD_RELEASE_RX_BUFF);
+}
+
+static inline uint32_t can_get_rx_message_counter()
+{
+ return CAN.rx_message_counter_reg.val;
+}
+
+/* -------------------- Interrupt and Alert Handlers ------------------------ */
+
+static void can_alert_handler(uint32_t alert_code, int *alert_req)
+{
+ if (p_can_obj->alerts_enabled & alert_code) {
+ //Signify alert has occurred
+ CAN_SET_FLAG(p_can_obj->alerts_triggered, alert_code);
+ *alert_req = 1;
+ if (p_can_obj->alerts_enabled & CAN_ALERT_AND_LOG) {
+ if (alert_code >= ALERT_LOG_LEVEL_ERROR) {
+ ESP_EARLY_LOGE(CAN_TAG, "Alert %d", alert_code);
+ } else if (alert_code >= ALERT_LOG_LEVEL_WARNING) {
+ ESP_EARLY_LOGW(CAN_TAG, "Alert %d", alert_code);
+ } else {
+ ESP_EARLY_LOGI(CAN_TAG, "Alert %d", alert_code);
+ }
+ }
+ }
+}
+
+static void can_intr_handler_err_warn(can_status_reg_t *status, BaseType_t *task_woken, int *alert_req)
+{
+ if (status->bus) {
+ if (status->error) {
+ //Bus-Off condition. TEC should set and held at 127, REC should be 0, reset mode entered
+ CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_BUS_OFF);
+ /* Note: REC is still allowed to increase during bus-off. REC > err_warn
+ can prevent "bus recovery complete" interrupt from occurring. Set to
+ listen only mode to freeze REC. */
+ can_config_mode(CAN_MODE_LISTEN_ONLY);
+ can_alert_handler(CAN_ALERT_BUS_OFF, alert_req);
+ } else {
+ //Bus-recovery in progress. TEC has dropped below error warning limit
+ can_alert_handler(CAN_ALERT_RECOVERY_IN_PROGRESS, alert_req);
+ }
+ } else {
+ if (status->error) {
+ //TEC or REC surpassed error warning limit
+ CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_ERR_WARN);
+ can_alert_handler(CAN_ALERT_ABOVE_ERR_WARN, alert_req);
+ } else if (p_can_obj->control_flags & CTRL_FLAG_RECOVERING) {
+ //Bus recovery complete.
+ can_enter_reset_mode();
+ //Reset and set flags to the equivalent of the stopped state
+ CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_RECOVERING | CTRL_FLAG_ERR_WARN |
+ CTRL_FLAG_ERR_PASSIVE | CTRL_FLAG_BUS_OFF |
+ CTRL_FLAG_TX_BUFF_OCCUPIED);
+ CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_STOPPED);
+ can_alert_handler(CAN_ALERT_BUS_RECOVERED, alert_req);
+ } else {
+ //TEC and REC are both below error warning
+ CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_ERR_WARN);
+ can_alert_handler(CAN_ALERT_BELOW_ERR_WARN, alert_req);
+ }
+ }
+}
+
+static void can_intr_handler_err_passive(int *alert_req)
+{
+ uint32_t tec, rec;
+ can_get_error_counters(&tec, &rec);
+ if (tec >= DRIVER_DEFAULT_ERR_PASS_CNT || rec >= DRIVER_DEFAULT_ERR_PASS_CNT) {
+ //Entered error passive
+ CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_ERR_PASSIVE);
+ can_alert_handler(CAN_ALERT_ERR_PASS, alert_req);
+ } else {
+ //Returned to error active
+ CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_ERR_PASSIVE);
+ can_alert_handler(CAN_ALERT_ERR_ACTIVE, alert_req);
+ }
+}
+
+static void can_intr_handler_bus_err(int *alert_req)
+{
+ // ECC register is read to re-arm bus error interrupt. ECC is not used
+ (void) can_get_error_code_capture();
+ p_can_obj->bus_error_count++;
+ can_alert_handler(CAN_ALERT_BUS_ERROR, alert_req);
+}
+
+static void can_intr_handler_arb_lost(int *alert_req)
+{
+ //ALC register is read to re-arm arb lost interrupt. ALC is not used
+ (void) can_get_arbitration_lost_capture();
+ p_can_obj->arb_lost_count++;
+ can_alert_handler(CAN_ALERT_ARB_LOST, alert_req);
+}
+
+static void can_intr_handler_rx(BaseType_t *task_woken, int *alert_req)
+{
+ can_rx_msg_cnt_reg_t msg_count_reg;
+ msg_count_reg.val = can_get_rx_message_counter();
+
+ for (int i = 0; i < msg_count_reg.rx_message_counter; i++) {
+ can_frame_t frame;
+ can_get_rx_buffer_and_clear(&frame);
+ //Copy frame into RX Queue
+ if (xQueueSendFromISR(p_can_obj->rx_queue, &frame, task_woken) == pdTRUE) {
+ p_can_obj->rx_msg_count++;
+ } else {
+ p_can_obj->rx_missed_count++;
+ can_alert_handler(CAN_ALERT_RX_QUEUE_FULL, alert_req);
+ }
+ }
+}
+
+static void can_intr_handler_tx(can_status_reg_t *status, int *alert_req)
+{
+ //Handle previously transmitted frame
+ if (status->tx_complete) {
+ can_alert_handler(CAN_ALERT_TX_SUCCESS, alert_req);
+ } else {
+ p_can_obj->tx_failed_count++;
+ can_alert_handler(CAN_ALERT_TX_FAILED, alert_req);
+ }
+
+ //Update TX message count
+ p_can_obj->tx_msg_count--;
+ configASSERT(p_can_obj->tx_msg_count >= 0); //Sanity check
+
+ //Check if there are more frames to transmit
+ if (p_can_obj->tx_msg_count > 0 && p_can_obj->tx_queue != NULL) {
+ can_frame_t frame;
+ configASSERT(xQueueReceiveFromISR(p_can_obj->tx_queue, &frame, NULL) == pdTRUE);
+ can_set_tx_buffer_and_transmit(&frame);
+ } else {
+ //No more frames to transmit
+ CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
+ can_alert_handler(CAN_ALERT_TX_IDLE, alert_req);
+ }
+}
+
+static void can_intr_handler_main(void *arg)
+{
+ BaseType_t task_woken = pdFALSE;
+ int alert_req = 0;
+ can_status_reg_t status;
+ can_intr_reg_t intr_reason;
+
+ CAN_ENTER_CRITICAL();
+ status.val = can_get_status();
+ intr_reason.val = (p_can_obj != NULL) ? can_get_interrupt_reason() : 0; //Incase intr occurs whilst driver is being uninstalled
+
+ //Handle error counter related interrupts
+ if (intr_reason.err_warn) {
+ //Triggers when Bus-Status or Error-status bits change
+ can_intr_handler_err_warn(&status, &task_woken, &alert_req);
+ }
+ if (intr_reason.err_passive) {
+ //Triggers when entering/returning error passive/active state
+ can_intr_handler_err_passive(&alert_req);
+ }
+
+ //Handle other error interrupts
+ if (intr_reason.bus_err) {
+ //Triggers when an error (Bit, Stuff, CRC, Form, ACK) occurs on the CAN bus
+ can_intr_handler_bus_err(&alert_req);
+ }
+ if (intr_reason.arb_lost) {
+ //Triggers when arbitration is lost
+ can_intr_handler_arb_lost(&alert_req);
+ }
+ //Todo: Check data overrun bug where interrupt does not trigger even when enabled
+
+ //Handle TX/RX interrupts
+ if (intr_reason.rx) {
+ //Triggers when RX buffer has one or more frames. Disabled if RX Queue length = 0
+ can_intr_handler_rx(&task_woken, &alert_req);
+ }
+ if (intr_reason.tx) {
+ //Triggers when TX buffer becomes free after a transmission
+ can_intr_handler_tx(&status, &alert_req);
+ }
+ /* Todo: Check possible bug where transmitting self reception request then
+ clearing rx buffer will cancel the transmission. */
+ CAN_EXIT_CRITICAL();
+
+ if (p_can_obj->alert_semphr != NULL && alert_req) {
+ //Give semaphore if alerts were triggered
+ xSemaphoreGiveFromISR(p_can_obj->alert_semphr, &task_woken);
+ }
+ if (task_woken == pdTRUE) {
+ portYIELD_FROM_ISR();
+ }
+}
+
+/* ---------------------- Frame and GPIO functions ------------------------- */
+
+static void can_format_frame(uint32_t id, uint8_t dlc, const uint8_t *data, uint32_t flags, can_frame_t *tx_frame)
+{
+ /* 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. */
+ //Set frame information
+ tx_frame->dlc = dlc;
+ tx_frame->rtr = (flags & CAN_MSG_FLAG_RTR) ? 1 : 0;
+ tx_frame->frame_format = (flags & CAN_MSG_FLAG_EXTD) ? 1 : 0;
+ tx_frame->self_reception = (flags & CAN_MSG_FLAG_SELF) ? 1 : 0;
+ tx_frame->single_shot = (flags & CAN_MSG_FLAG_SS) ? 1 : 0;
+
+ //Set ID
+ int id_len = (flags & CAN_MSG_FLAG_EXTD) ? FRAME_EXTD_ID_LEN : FRAME_STD_ID_LEN;
+ uint8_t *id_buffer = (flags & CAN_MSG_FLAG_EXTD) ? tx_frame->extended.id : tx_frame->standard.id;
+ //Split ID into 4 or 2 bytes, and turn into big-endian with left alignment (<< 3 or 5)
+ uint32_t id_temp = (flags & CAN_MSG_FLAG_EXTD) ? __builtin_bswap32((id & CAN_EXTD_ID_MASK) << 3) : //((id << 3) >> 8*(3-i))
+ __builtin_bswap16((id & CAN_STD_ID_MASK) << 5); //((id << 5) >> 8*(1-i))
+ for (int i = 0; i < id_len; i++) {
+ id_buffer[i] = (id_temp >> (8 * i)) & 0xFF; //Copy big-endian ID byte by byte
+ }
+
+ //Set Data.
+ uint8_t *data_buffer = (flags & CAN_MSG_FLAG_EXTD) ? tx_frame->extended.data : tx_frame->standard.data;
+ for (int i = 0; (i < dlc) && (i < FRAME_MAX_DATA_LEN); i++) { //Handle case where dlc is > 8
+ data_buffer[i] = data[i];
+ }
+}
+
+static void can_parse_frame(can_frame_t *rx_frame, uint32_t *id, uint8_t *dlc, uint8_t *data, uint32_t *flags)
+{
+ //This function decodes a frame structure into it's constituent components.
+
+ //Copy frame information
+ *dlc = rx_frame->dlc;
+ *flags = 0;
+ *flags |= (rx_frame->dlc > FRAME_MAX_DATA_LEN) ? CAN_MSG_FLAG_DLC_NON_COMP : 0;
+ *flags |= (rx_frame->rtr) ? CAN_MSG_FLAG_RTR : 0;
+ *flags |= (rx_frame->frame_format) ? CAN_MSG_FLAG_EXTD : 0;
+
+ //Copy ID
+ int id_len = (rx_frame->frame_format) ? FRAME_EXTD_ID_LEN : FRAME_STD_ID_LEN;
+ uint8_t *id_buffer = (rx_frame->frame_format) ? rx_frame->extended.id : rx_frame->standard.id;
+ uint32_t id_temp = 0;
+ for (int i = 0; i < id_len; i++) {
+ id_temp |= id_buffer[i] << (8 * i); //Copy big-endian ID byte by byte
+ }
+ //Revert endianness of 4 or 2 byte ID, and shift into 29 or 11 bit ID
+ id_temp = (rx_frame->frame_format) ? (__builtin_bswap32(id_temp) >> 3) : //((byte[i] << 8*(3-i)) >> 3)
+ (__builtin_bswap16(id_temp) >> 5); //((byte[i] << 8*(1-i)) >> 5)
+ *id = id_temp & ((rx_frame->frame_format) ? CAN_EXTD_ID_MASK : CAN_STD_ID_MASK);
+
+ //Copy data
+ uint8_t *data_buffer = (rx_frame->frame_format) ? rx_frame->extended.data : rx_frame->standard.data;
+ for (int i = 0; (i < rx_frame->dlc) && (i < FRAME_MAX_DATA_LEN); i++) {
+ data[i] = data_buffer[i];
+ }
+ //Set remaining bytes of data to 0
+ for (int i = rx_frame->dlc; i < FRAME_MAX_DATA_LEN; i++) {
+ data[i] = 0;
+ }
+}
+
+static void can_configure_gpio(gpio_num_t tx, gpio_num_t rx, gpio_num_t clkout, gpio_num_t bus_status)
+{
+ //Set TX pin
+ gpio_set_pull_mode(tx, GPIO_FLOATING);
+ gpio_matrix_out(tx, CAN_TX_IDX, false, false);
+ gpio_pad_select_gpio(tx);
+
+ //Set RX pin
+ gpio_set_pull_mode(rx, GPIO_FLOATING);
+ gpio_matrix_in(rx, CAN_RX_IDX, false);
+ gpio_pad_select_gpio(rx);
+
+ //Configure output clock pin (Optional)
+ if (clkout >= 0 && clkout < GPIO_NUM_MAX) {
+ gpio_set_pull_mode(clkout, GPIO_FLOATING);
+ gpio_matrix_out(clkout, CAN_CLKOUT_IDX, false, false);
+ gpio_pad_select_gpio(clkout);
+ }
+
+ //Configure bus status pin (Optional)
+ if (bus_status >= 0 && bus_status < GPIO_NUM_MAX) {
+ gpio_set_pull_mode(bus_status, GPIO_FLOATING);
+ gpio_matrix_out(bus_status, CAN_BUS_OFF_ON_IDX, false, false);
+ gpio_pad_select_gpio(bus_status);
+ }
+}
+
+/* ---------------------------- Public Functions ---------------------------- */
+
+esp_err_t can_driver_install(const can_general_config_t *g_config, const can_timing_config_t *t_config, const can_filter_config_t *f_config)
+{
+ //Check arguments and state
+ CAN_CHECK(p_can_obj == NULL, ESP_ERR_INVALID_STATE); //Check is driver is already installed
+ CAN_CHECK(g_config != NULL, ESP_ERR_INVALID_ARG);
+ CAN_CHECK(t_config != NULL, ESP_ERR_INVALID_ARG);
+ CAN_CHECK(f_config != NULL, ESP_ERR_INVALID_ARG);
+ CAN_CHECK(g_config->rx_queue_len > 0, ESP_ERR_INVALID_ARG);
+ CAN_CHECK(g_config->tx_io >= 0 && g_config->tx_io < GPIO_NUM_MAX, ESP_ERR_INVALID_ARG);
+ CAN_CHECK(g_config->rx_io >= 0 && g_config->rx_io < GPIO_NUM_MAX, ESP_ERR_INVALID_ARG);
+ esp_err_t ret;
+
+ //Initialize CAN object
+ p_can_obj = calloc(1, sizeof(can_obj_t));
+ CAN_CHECK(p_can_obj != NULL, ESP_ERR_NO_MEM);
+ p_can_obj->tx_queue = (g_config->tx_queue_len > 0) ? xQueueCreate(g_config->tx_queue_len, sizeof(can_frame_t)) : NULL;
+ p_can_obj->rx_queue = xQueueCreate(g_config->rx_queue_len, sizeof(can_frame_t));
+ p_can_obj->alert_semphr = xSemaphoreCreateBinary();
+ if ((g_config->tx_queue_len > 0 && p_can_obj->tx_queue == NULL) ||
+ p_can_obj->rx_queue == NULL || p_can_obj->alert_semphr == NULL) {
+ ret = ESP_ERR_NO_MEM;
+ goto err;
+ }
+ p_can_obj->control_flags = CTRL_FLAG_STOPPED;
+ p_can_obj->control_flags |= (g_config->mode == CAN_MODE_NO_ACK) ? CTRL_FLAG_SELF_TEST : 0;
+ p_can_obj->control_flags |= (g_config->mode == CAN_MODE_LISTEN_ONLY) ? CTRL_FLAG_LISTEN_ONLY : 0;
+ p_can_obj->tx_msg_count = 0;
+ p_can_obj->rx_msg_count = 0;
+ p_can_obj->tx_failed_count = 0;
+ p_can_obj->rx_missed_count = 0;
+ p_can_obj->arb_lost_count = 0;
+ p_can_obj->bus_error_count = 0;
+ p_can_obj->alerts_enabled = g_config->alerts_enabled;
+ p_can_obj->alerts_triggered = 0;
+
+ CAN_ENTER_CRITICAL();
+ //Initialize CAN peripheral
+ periph_module_enable(PERIPH_CAN_MODULE); //Enable APB CLK to CAN peripheral
+ configASSERT(can_enter_reset_mode() == ESP_OK); //Must enter reset mode to write to config registers
+ can_config_pelican(); //Use PeliCAN addresses
+ /* Note: REC is allowed to increase even in reset mode. Listen only mode
+ will freeze REC. The desired mode will be set when can_start() is called. */
+ can_config_mode(CAN_MODE_LISTEN_ONLY);
+ can_config_interrupts(DRIVER_DEFAULT_INTERRUPTS);
+ can_config_bus_timing(t_config->brp, t_config->sjw, t_config->tseg_1, t_config->tseg_2, t_config->triple_sampling);
+ can_config_error(DRIVER_DEFAULT_EWL, DRIVER_DEFAULT_REC, DRIVER_DEFAULT_TEC);
+ can_config_acceptance_filter(f_config->acceptance_code, f_config->acceptance_mask, f_config->single_filter);
+ can_config_clk_out(g_config->clkout_divider);
+ //Allocate GPIO and Interrupts
+ can_configure_gpio(g_config->tx_io, g_config->rx_io, g_config->clkout_io, g_config->bus_off_io);
+ (void) can_get_interrupt_reason(); //Read interrupt reg to clear it before allocating ISR
+ ESP_ERROR_CHECK(esp_intr_alloc(ETS_CAN_INTR_SOURCE, 0, can_intr_handler_main, NULL, &p_can_obj->isr_handle));
+ CAN_EXIT_CRITICAL();
+ //Todo: Allow interrupt to be registered to specified CPU
+
+ //CAN module is still in reset mode, users need to call can_start() afterwards
+ return ESP_OK;
+
+ err:
+ //Cleanup and return error
+ if (p_can_obj != NULL) {
+ if (p_can_obj->tx_queue != NULL) {
+ vQueueDelete(p_can_obj->tx_queue);
+ p_can_obj->tx_queue = NULL;
+ }
+ if (p_can_obj->rx_queue != NULL) {
+ vQueueDelete(p_can_obj->rx_queue);
+ p_can_obj->rx_queue = NULL;
+ }
+ if (p_can_obj->alert_semphr != NULL) {
+ vSemaphoreDelete(p_can_obj->alert_semphr);
+ p_can_obj->alert_semphr = NULL;
+ }
+ free(p_can_obj);
+ }
+ return ret;
+}
+
+esp_err_t can_driver_uninstall()
+{
+ //Check state
+ CAN_ENTER_CRITICAL();
+ CAN_CHECK_FROM_CRIT(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
+ CAN_CHECK_FROM_CRIT(p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF), ESP_ERR_INVALID_STATE);
+
+ //Clear registers
+ configASSERT(can_enter_reset_mode() == ESP_OK); //Enter reset mode to stop any CAN bus activity
+ (void) can_get_interrupt_reason();
+ (void) can_get_arbitration_lost_capture();
+ (void) can_get_error_code_capture();
+
+ ESP_ERROR_CHECK(esp_intr_free(p_can_obj->isr_handle)); //Free interrupt
+ periph_module_disable(PERIPH_CAN_MODULE); //Disable CAN peripheral
+ //Delete queues, semaphores
+ if (p_can_obj->tx_queue != NULL) {
+ vQueueDelete(p_can_obj->tx_queue);
+ }
+ vQueueDelete(p_can_obj->rx_queue);
+ vSemaphoreDelete(p_can_obj->alert_semphr);
+ free(p_can_obj); //Free can driver object
+ CAN_EXIT_CRITICAL();
+
+ return ESP_OK;
+}
+
+esp_err_t can_start()
+{
+ //Check state
+ CAN_ENTER_CRITICAL();
+ CAN_CHECK_FROM_CRIT(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
+ CAN_CHECK_FROM_CRIT(p_can_obj->control_flags & CTRL_FLAG_STOPPED, ESP_ERR_INVALID_STATE);
+
+ //Reset RX queue, and RX message count
+ xQueueReset(p_can_obj->rx_queue);
+ p_can_obj->rx_msg_count = 0;
+ configASSERT(can_enter_reset_mode() == ESP_OK); //Should already be in bus-off mode, set again to make sure
+
+ //Currently in listen only mode, need to set to mode specified by configuration
+ can_mode_t mode;
+ if (p_can_obj->control_flags & CTRL_FLAG_SELF_TEST) {
+ mode = CAN_MODE_NO_ACK;
+ } else if (p_can_obj->control_flags & CTRL_FLAG_LISTEN_ONLY) {
+ mode = CAN_MODE_LISTEN_ONLY;
+ } else {
+ mode = CAN_MODE_NORMAL;
+ }
+ can_config_mode(mode); //Set mode
+ (void) can_get_interrupt_reason(); //Clear interrupt register
+ configASSERT(can_exit_reset_mode() == ESP_OK);
+
+ CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_STOPPED);
+ CAN_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t can_stop()
+{
+ //Check state
+ CAN_ENTER_CRITICAL();
+ CAN_CHECK_FROM_CRIT(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
+ CAN_CHECK_FROM_CRIT(!(p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF)), ESP_ERR_INVALID_STATE);
+
+ //Clear interrupts and reset flags
+ configASSERT(can_enter_reset_mode() == ESP_OK);
+ (void) can_get_interrupt_reason(); //Read interrupt register to clear interrupts
+ can_config_mode(CAN_MODE_LISTEN_ONLY); //Set to listen only mode to freeze REC
+ CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
+ CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_STOPPED);
+
+ //Reset TX Queue and message count
+ if (p_can_obj->tx_queue != NULL) {
+ xQueueReset(p_can_obj->tx_queue);
+ }
+ p_can_obj->tx_msg_count = 0;
+
+ CAN_EXIT_CRITICAL();
+
+ return ESP_OK;
+}
+
+esp_err_t can_transmit(const can_message_t *message, TickType_t ticks_to_wait)
+{
+ //Check arguments
+ CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
+ CAN_CHECK(message != NULL, ESP_ERR_INVALID_ARG);
+ CAN_CHECK((message->data_length_code <= FRAME_MAX_DATA_LEN) || (message->flags & CAN_MSG_FLAG_DLC_NON_COMP), ESP_ERR_INVALID_ARG);
+
+ CAN_ENTER_CRITICAL();
+ //Check State
+ CAN_CHECK_FROM_CRIT(!(p_can_obj->control_flags & CTRL_FLAG_LISTEN_ONLY), ESP_ERR_NOT_SUPPORTED);
+ CAN_CHECK_FROM_CRIT(!(p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF)), ESP_ERR_INVALID_STATE);
+ //Format frame
+ esp_err_t ret = ESP_FAIL;
+ can_frame_t tx_frame;
+ can_format_frame(message->identifier, message->data_length_code, message->data, message->flags, &tx_frame);
+ //Check if frame can be sent immediately
+ if ((p_can_obj->tx_msg_count == 0) && !(p_can_obj->control_flags & CTRL_FLAG_TX_BUFF_OCCUPIED)) {
+ //No other frames waiting to transmit. Bypass queue and transmit immediately
+ can_set_tx_buffer_and_transmit(&tx_frame);
+ p_can_obj->tx_msg_count++;
+ CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
+ ret = ESP_OK;
+ }
+ CAN_EXIT_CRITICAL();
+
+ if (ret != ESP_OK) {
+ if (p_can_obj->tx_queue == NULL) {
+ //TX Queue is disabled and TX buffer is occupied, message was not sent
+ ret = ESP_FAIL;
+ } else if (xQueueSend(p_can_obj->tx_queue, &tx_frame, ticks_to_wait) == pdTRUE) {
+ //Copied to TX Queue
+ CAN_ENTER_CRITICAL();
+ if (p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_STOPPED)) {
+ //TX queue was reset (due to stop/bus_off), remove copied frame from queue to prevent transmission
+ configASSERT(xQueueReceive(p_can_obj->tx_queue, &tx_frame, 0) == pdTRUE);
+ ret = ESP_ERR_INVALID_STATE;
+ } else if ((p_can_obj->tx_msg_count == 0) && !(p_can_obj->control_flags & CTRL_FLAG_TX_BUFF_OCCUPIED)) {
+ //TX buffer was freed during copy, manually trigger transmission
+ configASSERT(xQueueReceive(p_can_obj->tx_queue, &tx_frame, 0) == pdTRUE);
+ can_set_tx_buffer_and_transmit(&tx_frame);
+ p_can_obj->tx_msg_count++;
+ CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
+ ret = ESP_OK;
+ } else {
+ //Frame was copied to queue, waiting to be transmitted
+ p_can_obj->tx_msg_count++;
+ ret = ESP_OK;
+ }
+ CAN_EXIT_CRITICAL();
+ } else {
+ //Timed out waiting for free space on TX queue
+ ret = ESP_ERR_TIMEOUT;
+ }
+ }
+ return ret;
+}
+
+esp_err_t can_receive(can_message_t *message, TickType_t ticks_to_wait)
+{
+ //Check arguments and state
+ CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
+ CAN_CHECK(message != NULL, ESP_ERR_INVALID_ARG);
+
+ //Get frame from RX Queue or RX Buffer
+ can_frame_t rx_frame;
+ if (xQueueReceive(p_can_obj->rx_queue, &rx_frame, ticks_to_wait) != pdTRUE) {
+ return ESP_ERR_TIMEOUT;
+ }
+
+ CAN_ENTER_CRITICAL();
+ p_can_obj->rx_msg_count--;
+ CAN_EXIT_CRITICAL();
+
+ //Decode frame
+ can_parse_frame(&rx_frame, &(message->identifier), &(message->data_length_code), message->data, &(message->flags));
+ return ESP_OK;
+}
+
+esp_err_t can_read_alerts(uint32_t *alerts, TickType_t ticks_to_wait)
+{
+ //Check arguments and state
+ CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
+ CAN_CHECK(alerts != NULL, ESP_ERR_INVALID_ARG);
+
+ //Wait for an alert to occur
+ if (xSemaphoreTake(p_can_obj->alert_semphr, ticks_to_wait) == pdTRUE) {
+ CAN_ENTER_CRITICAL();
+ *alerts = p_can_obj->alerts_triggered;
+ p_can_obj->alerts_triggered = 0; //Clear triggered alerts
+ CAN_EXIT_CRITICAL();
+ return ESP_OK;
+ } else {
+ *alerts = 0;
+ return ESP_ERR_TIMEOUT;
+ }
+}
+
+esp_err_t can_reconfigure_alerts(uint32_t alerts_enabled, uint32_t *current_alerts)
+{
+ CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
+ CAN_ENTER_CRITICAL();
+ uint32_t cur_alerts;
+ cur_alerts = can_read_alerts(&cur_alerts, 0); //Clear any unhandled alerts
+ p_can_obj->alerts_enabled = alerts_enabled; //Update enabled alerts
+ CAN_EXIT_CRITICAL();
+
+ if (current_alerts != NULL) {
+ *current_alerts = cur_alerts;
+ }
+ return ESP_OK;
+}
+
+esp_err_t can_initiate_recovery()
+{
+ CAN_ENTER_CRITICAL();
+ //Check state
+ CAN_CHECK_FROM_CRIT(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
+ CAN_CHECK_FROM_CRIT(p_can_obj->control_flags & CTRL_FLAG_BUS_OFF, ESP_ERR_INVALID_STATE);
+ CAN_CHECK_FROM_CRIT(!(p_can_obj->control_flags & CTRL_FLAG_RECOVERING), ESP_ERR_INVALID_STATE);
+
+ //Reset TX Queue/Counters
+ if (p_can_obj->tx_queue != NULL) {
+ xQueueReset(p_can_obj->tx_queue);
+ }
+ p_can_obj->tx_msg_count = 0;
+ CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
+ CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_RECOVERING);
+
+ //Trigger start of recovery process
+ configASSERT(can_exit_reset_mode() == ESP_OK);
+ CAN_EXIT_CRITICAL();
+
+ return ESP_OK;
+}
+
+esp_err_t can_get_status_info(can_status_info_t *status_info)
+{
+ //Check parameters and state
+ CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
+ CAN_CHECK(status_info != NULL, ESP_ERR_INVALID_ARG);
+
+ CAN_ENTER_CRITICAL();
+ uint32_t tec, rec;
+ can_get_error_counters(&tec, &rec);
+ status_info->tx_error_counter = tec;
+ status_info->rx_error_counter = rec;
+ status_info->msgs_to_tx = p_can_obj->tx_msg_count;
+ status_info->msgs_to_rx = p_can_obj->rx_msg_count;
+ status_info->tx_failed_count = p_can_obj->tx_failed_count;
+ status_info->rx_missed_count = p_can_obj->rx_missed_count;
+ status_info->arb_lost_count = p_can_obj->arb_lost_count;
+ status_info->bus_error_count = p_can_obj->bus_error_count;
+ if (p_can_obj->control_flags & CTRL_FLAG_RECOVERING) {
+ status_info->state = CAN_STATE_RECOVERING;
+ } else if (p_can_obj->control_flags & CTRL_FLAG_BUS_OFF) {
+ status_info->state = CAN_STATE_BUS_OFF;
+ } else if (p_can_obj->control_flags & CTRL_FLAG_STOPPED) {
+ status_info->state = CAN_STATE_STOPPED;
+ } else {
+ status_info->state = CAN_STATE_RUNNING;
+ }
+ CAN_EXIT_CRITICAL();
+
+ return ESP_OK;
+}
+
diff --git a/components/driver/gpio.c b/components/driver/gpio.c
index e017cd87df..d81d2c25c3 100644
--- a/components/driver/gpio.c
+++ b/components/driver/gpio.c
@@ -21,6 +21,7 @@
#include "driver/rtc_io.h"
#include "soc/soc.h"
#include "esp_log.h"
+#include "soc/gpio_periph.h"
static const char* GPIO_TAG = "gpio";
#define GPIO_CHECK(a, str, ret_val) \
@@ -29,49 +30,6 @@ static const char* GPIO_TAG = "gpio";
return (ret_val); \
}
-const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = {
- IO_MUX_GPIO0_REG,
- IO_MUX_GPIO1_REG,
- IO_MUX_GPIO2_REG,
- IO_MUX_GPIO3_REG,
- IO_MUX_GPIO4_REG,
- IO_MUX_GPIO5_REG,
- IO_MUX_GPIO6_REG,
- IO_MUX_GPIO7_REG,
- IO_MUX_GPIO8_REG,
- IO_MUX_GPIO9_REG,
- IO_MUX_GPIO10_REG,
- IO_MUX_GPIO11_REG,
- IO_MUX_GPIO12_REG,
- IO_MUX_GPIO13_REG,
- IO_MUX_GPIO14_REG,
- IO_MUX_GPIO15_REG,
- IO_MUX_GPIO16_REG,
- IO_MUX_GPIO17_REG,
- IO_MUX_GPIO18_REG,
- IO_MUX_GPIO19_REG,
- 0,
- IO_MUX_GPIO21_REG,
- IO_MUX_GPIO22_REG,
- IO_MUX_GPIO23_REG,
- 0,
- IO_MUX_GPIO25_REG,
- IO_MUX_GPIO26_REG,
- IO_MUX_GPIO27_REG,
- 0,
- 0,
- 0,
- 0,
- IO_MUX_GPIO32_REG,
- IO_MUX_GPIO33_REG,
- IO_MUX_GPIO34_REG,
- IO_MUX_GPIO35_REG,
- IO_MUX_GPIO36_REG,
- IO_MUX_GPIO37_REG,
- IO_MUX_GPIO38_REG,
- IO_MUX_GPIO39_REG,
-};
-
typedef struct {
gpio_isr_t fn; /*!< isr function */
void* args; /*!< isr function args */
@@ -133,9 +91,19 @@ esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type)
return ESP_OK;
}
+static void gpio_intr_status_clr(gpio_num_t gpio_num)
+{
+ if (gpio_num < 32) {
+ GPIO.status_w1tc = BIT(gpio_num);
+ } else {
+ GPIO.status1_w1tc.intr_st = BIT(gpio_num - 32);
+ }
+}
+
static esp_err_t gpio_intr_enable_on_core (gpio_num_t gpio_num, uint32_t core_id)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
+ gpio_intr_status_clr(gpio_num);
if (core_id == 0) {
GPIO.pin[gpio_num].int_ena = GPIO_PRO_CPU_INTR_ENA; //enable pro cpu intr
} else {
@@ -153,6 +121,7 @@ esp_err_t gpio_intr_disable(gpio_num_t gpio_num)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
GPIO.pin[gpio_num].int_ena = 0; //disable GPIO intr
+ gpio_intr_status_clr(gpio_num);
return ESP_OK;
}
@@ -291,7 +260,11 @@ esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)
}
do {
io_reg = GPIO_PIN_MUX_REG[io_num];
- if (((gpio_pin_mask >> io_num) & BIT(0)) && io_reg) {
+ if (((gpio_pin_mask >> io_num) & BIT(0))) {
+ if (!io_reg) {
+ ESP_LOGE(GPIO_TAG, "IO%d is not a valid GPIO",io_num);
+ return ESP_ERR_INVALID_ARG;
+ }
if(RTC_GPIO_IS_VALID_GPIO(io_num)){
rtc_gpio_deinit(io_num);
}
@@ -339,6 +312,21 @@ esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)
return ESP_OK;
}
+esp_err_t gpio_reset_pin(gpio_num_t gpio_num)
+{
+ assert(gpio_num >= 0 && GPIO_IS_VALID_GPIO(gpio_num));
+ gpio_config_t cfg = {
+ .pin_bit_mask = BIT64(gpio_num),
+ .mode = GPIO_MODE_DISABLE,
+ //for powersave reasons, the GPIO should not be floating, select pullup
+ .pull_up_en = true,
+ .pull_down_en = false,
+ .intr_type = GPIO_INTR_DISABLE,
+ };
+ gpio_config(&cfg);
+ return ESP_OK;
+}
+
void IRAM_ATTR gpio_intr_service(void* arg)
{
//GPIO intr process
diff --git a/components/driver/i2c.c b/components/driver/i2c.c
index 1d904fdcb7..e21c137c4a 100644
--- a/components/driver/i2c.c
+++ b/components/driver/i2c.c
@@ -1,1378 +1,1378 @@
-// Copyright 2015-2016 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.
-#include
-#include
-#include "esp_types.h"
-#include "esp_attr.h"
-#include "esp_intr.h"
-#include "esp_log.h"
-#include "malloc.h"
-#include "freertos/FreeRTOS.h"
-#include "freertos/semphr.h"
-#include "freertos/xtensa_api.h"
-#include "freertos/task.h"
-#include "freertos/ringbuf.h"
-#include "soc/dport_reg.h"
-#include "soc/i2c_struct.h"
-#include "soc/i2c_reg.h"
-#include "driver/i2c.h"
-#include "driver/gpio.h"
-#include "driver/periph_ctrl.h"
-
-static const char* I2C_TAG = "i2c";
-#define I2C_CHECK(a, str, ret) if(!(a)) { \
- ESP_LOGE(I2C_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
- return (ret); \
- }
-
-static portMUX_TYPE i2c_spinlock[I2C_NUM_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED};
-/* DRAM_ATTR is required to avoid I2C array placed in flash, due to accessed from ISR */
-static DRAM_ATTR i2c_dev_t* const I2C[I2C_NUM_MAX] = { &I2C0, &I2C1 };
-
-#define I2C_ENTER_CRITICAL_ISR(mux) portENTER_CRITICAL_ISR(mux)
-#define I2C_EXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL_ISR(mux)
-#define I2C_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux)
-#define I2C_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux)
-
-#define I2C_DRIVER_ERR_STR "i2c driver install error"
-#define I2C_DRIVER_MALLOC_ERR_STR "i2c driver malloc error"
-#define I2C_NUM_ERROR_STR "i2c number error"
-#define I2C_TIMEING_VAL_ERR_STR "i2c timing value error"
-#define I2C_ADDR_ERROR_STR "i2c null address error"
-#define I2C_DRIVER_NOT_INSTALL_ERR_STR "i2c driver not installed"
-#define I2C_SLAVE_BUFFER_LEN_ERR_STR "i2c buffer size too small for slave mode"
-#define I2C_EVT_QUEUE_ERR_STR "i2c evt queue error"
-#define I2C_SEM_ERR_STR "i2c semaphore error"
-#define I2C_BUF_ERR_STR "i2c ringbuffer error"
-#define I2C_MASTER_MODE_ERR_STR "Only allowed in master mode"
-#define I2C_MODE_SLAVE_ERR_STR "Only allowed in slave mode"
-#define I2C_CMD_MALLOC_ERR_STR "i2c command link malloc error"
-#define I2C_TRANS_MODE_ERR_STR "i2c trans mode error"
-#define I2C_MODE_ERR_STR "i2c mode error"
-#define I2C_SDA_IO_ERR_STR "sda gpio number error"
-#define I2C_SCL_IO_ERR_STR "scl gpio number error"
-#define I2C_CMD_LINK_INIT_ERR_STR "i2c command link error"
-#define I2C_GPIO_PULLUP_ERR_STR "this i2c pin does not support internal pull-up"
-#define I2C_ACK_TYPE_ERR_STR "i2c ack type error"
-#define I2C_DATA_LEN_ERR_STR "i2c data read length error"
-#define I2C_PSRAM_BUFFER_WARN_STR "Using buffer allocated from psram"
-#define I2C_FIFO_FULL_THRESH_VAL (28)
-#define I2C_FIFO_EMPTY_THRESH_VAL (5)
-#define I2C_IO_INIT_LEVEL (1)
-#define I2C_CMD_ALIVE_INTERVAL_TICK (1000 / portTICK_PERIOD_MS)
-#define I2C_CMD_EVT_ALIVE (0)
-#define I2C_CMD_EVT_DONE (1)
-#define I2C_EVT_QUEUE_LEN (1)
-#define I2C_SLAVE_TIMEOUT_DEFAULT (32000) /* I2C slave timeout value, APB clock cycle number */
-#define I2C_SLAVE_SDA_SAMPLE_DEFAULT (10) /* I2C slave sample time after scl positive edge default value */
-#define I2C_SLAVE_SDA_HOLD_DEFAULT (10) /* I2C slave hold time after scl negative edge default value */
-#define I2C_MASTER_TOUT_CNUM_DEFAULT (8) /* I2C master timeout cycle number of I2C clock, after which the timeout interrupt will be triggered */
-#define I2C_ACKERR_CNT_MAX (10)
-
-typedef struct {
- uint8_t byte_num; /*!< cmd byte number */
- uint8_t ack_en; /*!< ack check enable */
- uint8_t ack_exp; /*!< expected ack level to get */
- uint8_t ack_val; /*!< ack value to send */
- uint8_t* data; /*!< data address */
- uint8_t byte_cmd; /*!< to save cmd for one byte command mode */
- i2c_opmode_t op_code; /*!< haredware cmd type */
-}i2c_cmd_t;
-
-typedef struct i2c_cmd_link{
- i2c_cmd_t cmd; /*!< command in current cmd link */
- struct i2c_cmd_link *next; /*!< next cmd link */
-} i2c_cmd_link_t;
-
-typedef struct {
- i2c_cmd_link_t* head; /*!< head of the command link */
- i2c_cmd_link_t* cur; /*!< last node of the command link */
- i2c_cmd_link_t* free; /*!< the first node to free of the command link */
-} i2c_cmd_desc_t;
-
-typedef enum {
- I2C_STATUS_READ, /*!< read status for current master command */
- I2C_STATUS_WRITE, /*!< write status for current master command */
- I2C_STATUS_IDLE, /*!< idle status for current master command */
- I2C_STATUS_ACK_ERROR, /*!< ack error status for current master command */
- I2C_STATUS_DONE, /*!< I2C command done */
- I2C_STATUS_TIMEOUT, /*!< I2C bus status error, and operation timeout */
-} i2c_status_t;
-
-typedef struct {
- int type;
-} i2c_cmd_evt_t;
-
-typedef struct {
- int i2c_num; /*!< I2C port number */
- int mode; /*!< I2C mode, master or slave */
- intr_handle_t intr_handle; /*!< I2C interrupt handle*/
- int cmd_idx; /*!< record current command index, for master mode */
- int status; /*!< record current command status, for master mode */
- int rx_cnt; /*!< record current read index, for master mode */
- uint8_t data_buf[I2C_FIFO_LEN]; /*!< a buffer to store i2c fifo data */
-
- i2c_cmd_desc_t cmd_link; /*!< I2C command link */
- QueueHandle_t cmd_evt_queue; /*!< I2C command event queue */
-#if CONFIG_SPIRAM_USE_MALLOC
- uint8_t* evt_queue_storage; /*!< The buffer that will hold the items in the queue */
- int intr_alloc_flags; /*!< Used to allocate the interrupt */
- StaticQueue_t evt_queue_buffer; /*!< The buffer that will hold the queue structure*/
-#endif
- xSemaphoreHandle cmd_mux; /*!< semaphore to lock command process */
- size_t tx_fifo_remain; /*!< tx fifo remain length, for master mode */
- size_t rx_fifo_remain; /*!< rx fifo remain length, for master mode */
-
- xSemaphoreHandle slv_rx_mux; /*!< slave rx buffer mux */
- xSemaphoreHandle slv_tx_mux; /*!< slave tx buffer mux */
- size_t rx_buf_length; /*!< rx buffer length */
- RingbufHandle_t rx_ring_buf; /*!< rx ringbuffer handler of slave mode */
- size_t tx_buf_length; /*!< tx buffer length */
- RingbufHandle_t tx_ring_buf; /*!< tx ringbuffer handler of slave mode */
-} i2c_obj_t;
-
-static i2c_obj_t *p_i2c_obj[I2C_NUM_MAX] = {0};
-static void i2c_isr_handler_default(void* arg);
-static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num);
-static esp_err_t IRAM_ATTR i2c_hw_fsm_reset(i2c_port_t i2c_num);
-
-/*
- For i2c master mode, we don't need to use a buffer for the data, the APIs will execute the master commands
-and return after all of the commands have been sent out or when error occurs. So when we send master commands,
-we should free or modify the source data only after the i2c_master_cmd_begin function returns.
- For i2c slave mode, we need a data buffer to stash the sending and receiving data, because the hardware fifo
-has only 32 bytes.
-*/
-esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_buf_len, size_t slv_tx_buf_len,
- int intr_alloc_flags)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(mode == I2C_MODE_MASTER || ( slv_rx_buf_len > 100 || slv_tx_buf_len > 100 ), I2C_SLAVE_BUFFER_LEN_ERR_STR,
- ESP_ERR_INVALID_ARG);
- uint32_t intr_mask = 0;
- if (p_i2c_obj[i2c_num] == NULL) {
-
-#if !CONFIG_SPIRAM_USE_MALLOC
- p_i2c_obj[i2c_num] = (i2c_obj_t*) calloc(1, sizeof(i2c_obj_t));
-#else
- if( !(intr_alloc_flags & ESP_INTR_FLAG_IRAM) ) {
- p_i2c_obj[i2c_num] = (i2c_obj_t*) calloc(1, sizeof(i2c_obj_t));
- } else {
- p_i2c_obj[i2c_num] = (i2c_obj_t*) heap_caps_calloc(1, sizeof(i2c_obj_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
- }
-#endif
- if (p_i2c_obj[i2c_num] == NULL) {
- ESP_LOGE(I2C_TAG, I2C_DRIVER_MALLOC_ERR_STR);
- return ESP_FAIL;
- }
- i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
- p_i2c->i2c_num = i2c_num;
- p_i2c->mode = mode;
- p_i2c->cmd_idx = 0;
- p_i2c->rx_cnt = 0;
- p_i2c->status = I2C_STATUS_IDLE;
-
-#if CONFIG_SPIRAM_USE_MALLOC
- p_i2c->intr_alloc_flags = intr_alloc_flags;
-#endif
- p_i2c->rx_fifo_remain = I2C_FIFO_LEN;
- p_i2c->tx_fifo_remain = I2C_FIFO_LEN;
-
- if (mode == I2C_MODE_SLAVE) {
- //we only use ringbuffer for slave mode.
- if (slv_rx_buf_len > 0) {
- p_i2c->rx_ring_buf = xRingbufferCreate(slv_rx_buf_len, RINGBUF_TYPE_BYTEBUF);
- if (p_i2c->rx_ring_buf == NULL) {
- ESP_LOGE(I2C_TAG, I2C_BUF_ERR_STR);
- goto err;
- }
- p_i2c->rx_buf_length = slv_rx_buf_len;
- } else {
- p_i2c->rx_ring_buf = NULL;
- p_i2c->rx_buf_length = 0;
- }
- if (slv_tx_buf_len > 0) {
- p_i2c->tx_ring_buf = xRingbufferCreate(slv_tx_buf_len, RINGBUF_TYPE_BYTEBUF);
- if (p_i2c->tx_ring_buf == NULL) {
- ESP_LOGE(I2C_TAG, I2C_BUF_ERR_STR);
- goto err;
- }
- p_i2c->tx_buf_length = slv_tx_buf_len;
- } else {
- p_i2c->tx_ring_buf = NULL;
- p_i2c->tx_buf_length = 0;
- }
- p_i2c->slv_rx_mux = xSemaphoreCreateMutex();
- p_i2c->slv_tx_mux = xSemaphoreCreateMutex();
- if (p_i2c->slv_rx_mux == NULL || p_i2c->slv_tx_mux == NULL) {
- ESP_LOGE(I2C_TAG, I2C_SEM_ERR_STR);
- goto err;
- }
- intr_mask |= ( I2C_RXFIFO_FULL_INT_ENA_M | I2C_TRANS_COMPLETE_INT_ENA_M);
- } else {
- //semaphore to sync sending process, because we only have 32 bytes for hardware fifo.
- p_i2c->cmd_mux = xSemaphoreCreateMutex();
-#if !CONFIG_SPIRAM_USE_MALLOC
- p_i2c->cmd_evt_queue = xQueueCreate(I2C_EVT_QUEUE_LEN, sizeof(i2c_cmd_evt_t));
-#else
- if( !(intr_alloc_flags & ESP_INTR_FLAG_IRAM) ) {
- p_i2c->cmd_evt_queue = xQueueCreate(I2C_EVT_QUEUE_LEN, sizeof(i2c_cmd_evt_t));
- } else {
- p_i2c->evt_queue_storage = (uint8_t *)heap_caps_calloc(I2C_EVT_QUEUE_LEN, sizeof(i2c_cmd_evt_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
- if( p_i2c->evt_queue_storage == NULL ) {
- ESP_LOGE(I2C_TAG, I2C_DRIVER_MALLOC_ERR_STR);
- goto err;
- }
- memset(&p_i2c->evt_queue_buffer, 0, sizeof(StaticQueue_t));
- p_i2c->cmd_evt_queue = xQueueCreateStatic(I2C_EVT_QUEUE_LEN, sizeof(i2c_cmd_evt_t), p_i2c->evt_queue_storage, &p_i2c->evt_queue_buffer);
- }
-#endif
- if (p_i2c->cmd_mux == NULL || p_i2c->cmd_evt_queue == NULL) {
- ESP_LOGE(I2C_TAG, I2C_SEM_ERR_STR);
- goto err;
- }
- //command link
- p_i2c->cmd_link.cur = NULL;
- p_i2c->cmd_link.head = NULL;
- p_i2c->cmd_link.free = NULL;
-
- p_i2c->tx_ring_buf = NULL;
- p_i2c->rx_buf_length = 0;
- p_i2c->tx_ring_buf = NULL;
- p_i2c->tx_buf_length = 0;
- intr_mask |= I2C_ARBITRATION_LOST_INT_ENA_M | I2C_TIME_OUT_INT_ST_M;
- }
- } else {
- ESP_LOGE(I2C_TAG, I2C_DRIVER_ERR_STR);
- return ESP_FAIL;
- }
- //hook isr handler
- i2c_isr_register(i2c_num, i2c_isr_handler_default, p_i2c_obj[i2c_num], intr_alloc_flags, &p_i2c_obj[i2c_num]->intr_handle);
- intr_mask |= ( I2C_TRANS_COMPLETE_INT_ENA_M |
- I2C_TRANS_START_INT_ENA_M |
- I2C_ACK_ERR_INT_ENA_M |
- I2C_RXFIFO_OVF_INT_ENA_M |
- I2C_SLAVE_TRAN_COMP_INT_ENA_M);
- I2C[i2c_num]->int_clr.val = intr_mask;
- I2C[i2c_num]->int_ena.val = intr_mask;
- return ESP_OK;
-
- err:
- //Some error has happened. Free/destroy all allocated things and return ESP_FAIL.
- if (p_i2c_obj[i2c_num]) {
- if (p_i2c_obj[i2c_num]->rx_ring_buf) {
- vRingbufferDelete(p_i2c_obj[i2c_num]->rx_ring_buf);
- p_i2c_obj[i2c_num]->rx_ring_buf = NULL;
- p_i2c_obj[i2c_num]->rx_buf_length = 0;
- }
- if (p_i2c_obj[i2c_num]->tx_ring_buf) {
- vRingbufferDelete(p_i2c_obj[i2c_num]->tx_ring_buf);
- p_i2c_obj[i2c_num]->tx_ring_buf = NULL;
- p_i2c_obj[i2c_num]->tx_buf_length = 0;
- }
- if (p_i2c_obj[i2c_num]->cmd_evt_queue) {
- vQueueDelete(p_i2c_obj[i2c_num]->cmd_evt_queue);
- p_i2c_obj[i2c_num]->cmd_evt_queue = NULL;
- }
- if (p_i2c_obj[i2c_num]->cmd_mux) {
- vSemaphoreDelete(p_i2c_obj[i2c_num]->cmd_mux);
- }
- if (p_i2c_obj[i2c_num]->slv_rx_mux) {
- vSemaphoreDelete(p_i2c_obj[i2c_num]->slv_rx_mux);
- }
- if (p_i2c_obj[i2c_num]->slv_tx_mux) {
- vSemaphoreDelete(p_i2c_obj[i2c_num]->slv_tx_mux);
- }
-#if CONFIG_SPIRAM_USE_MALLOC
- if (p_i2c_obj[i2c_num]->evt_queue_storage) {
- free(p_i2c_obj[i2c_num]->evt_queue_storage);
- p_i2c_obj[i2c_num]->evt_queue_storage = NULL;
- }
-#endif
- }
- free(p_i2c_obj[i2c_num]);
- p_i2c_obj[i2c_num] = NULL;
- return ESP_FAIL;
-}
-
-static esp_err_t i2c_hw_enable(i2c_port_t i2c_num)
-{
- if (i2c_num == I2C_NUM_0) {
- periph_module_enable(PERIPH_I2C0_MODULE);
- } else if (i2c_num == I2C_NUM_1) {
- periph_module_enable(PERIPH_I2C1_MODULE);
- }
- return ESP_OK;
-}
-
-static esp_err_t i2c_hw_disable(i2c_port_t i2c_num)
-{
- if (i2c_num == I2C_NUM_0) {
- periph_module_disable(PERIPH_I2C0_MODULE);
- } else if (i2c_num == I2C_NUM_1) {
- periph_module_disable(PERIPH_I2C1_MODULE);
- }
- return ESP_OK;
-}
-
-esp_err_t i2c_driver_delete(i2c_port_t i2c_num)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(p_i2c_obj[i2c_num] != NULL, I2C_DRIVER_ERR_STR, ESP_FAIL);
-
- i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
-
- I2C[i2c_num]->int_ena.val = 0;
- esp_intr_free(p_i2c->intr_handle);
- p_i2c->intr_handle = NULL;
-
- if (p_i2c->cmd_mux) {
- xSemaphoreTake(p_i2c->cmd_mux, portMAX_DELAY);
- vSemaphoreDelete(p_i2c->cmd_mux);
- }
- if (p_i2c_obj[i2c_num]->cmd_evt_queue) {
- vQueueDelete(p_i2c_obj[i2c_num]->cmd_evt_queue);
- p_i2c_obj[i2c_num]->cmd_evt_queue = NULL;
- }
- if (p_i2c->slv_rx_mux) {
- vSemaphoreDelete(p_i2c->slv_rx_mux);
- }
- if (p_i2c->slv_tx_mux) {
- vSemaphoreDelete(p_i2c->slv_tx_mux);
- }
-
- if (p_i2c->rx_ring_buf) {
- vRingbufferDelete(p_i2c->rx_ring_buf);
- p_i2c->rx_ring_buf = NULL;
- p_i2c->rx_buf_length = 0;
- }
- if (p_i2c->tx_ring_buf) {
- vRingbufferDelete(p_i2c->tx_ring_buf);
- p_i2c->tx_ring_buf = NULL;
- p_i2c->tx_buf_length = 0;
- }
-#if CONFIG_SPIRAM_USE_MALLOC
- if (p_i2c_obj[i2c_num]->evt_queue_storage) {
- free(p_i2c_obj[i2c_num]->evt_queue_storage);
- p_i2c_obj[i2c_num]->evt_queue_storage = NULL;
- }
-#endif
-
- free(p_i2c_obj[i2c_num]);
- p_i2c_obj[i2c_num] = NULL;
-
- i2c_hw_disable(i2c_num);
- return ESP_OK;
-}
-
-esp_err_t i2c_reset_tx_fifo(i2c_port_t i2c_num)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- I2C[i2c_num]->fifo_conf.tx_fifo_rst = 1;
- I2C[i2c_num]->fifo_conf.tx_fifo_rst = 0;
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-esp_err_t i2c_reset_rx_fifo(i2c_port_t i2c_num)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- I2C[i2c_num]->fifo_conf.rx_fifo_rst = 1;
- I2C[i2c_num]->fifo_conf.rx_fifo_rst = 0;
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-static void IRAM_ATTR i2c_isr_handler_default(void* arg)
-{
- i2c_obj_t* p_i2c = (i2c_obj_t*) arg;
- int i2c_num = p_i2c->i2c_num;
- uint32_t status = I2C[i2c_num]->int_status.val;
- int idx = 0;
-
- portBASE_TYPE HPTaskAwoken = pdFALSE;
- while (status != 0) {
- status = I2C[i2c_num]->int_status.val;
- if (status & I2C_TX_SEND_EMPTY_INT_ST_M) {
- I2C[i2c_num]->int_clr.tx_send_empty = 1;
- } else if (status & I2C_RX_REC_FULL_INT_ST_M) {
- I2C[i2c_num]->int_clr.rx_rec_full = 1;
- } else if (status & I2C_ACK_ERR_INT_ST_M) {
- I2C[i2c_num]->int_ena.ack_err = 0;
- I2C[i2c_num]->int_clr.ack_err = 1;
- if (p_i2c->mode == I2C_MODE_MASTER) {
- p_i2c_obj[i2c_num]->status = I2C_STATUS_ACK_ERROR;
- I2C[i2c_num]->int_clr.ack_err = 1;
- //get error ack value from slave device, stop the commands
- i2c_master_cmd_begin_static(i2c_num);
- }
- } else if (status & I2C_TRANS_START_INT_ST_M) {
- I2C[i2c_num]->int_clr.trans_start = 1;
- } else if (status & I2C_TIME_OUT_INT_ST_M) {
- I2C[i2c_num]->int_ena.time_out = 0;
- I2C[i2c_num]->int_clr.time_out = 1;
- p_i2c_obj[i2c_num]->status = I2C_STATUS_TIMEOUT;
- i2c_master_cmd_begin_static(i2c_num);
- } else if (status & I2C_TRANS_COMPLETE_INT_ST_M) {
- I2C[i2c_num]->int_clr.trans_complete = 1;
- if (p_i2c->mode == I2C_MODE_SLAVE) {
- int rx_fifo_cnt = I2C[i2c_num]->status_reg.rx_fifo_cnt;
- for (idx = 0; idx < rx_fifo_cnt; idx++) {
- p_i2c->data_buf[idx] = I2C[i2c_num]->fifo_data.data;
- }
- xRingbufferSendFromISR(p_i2c->rx_ring_buf, p_i2c->data_buf, rx_fifo_cnt, &HPTaskAwoken);
- I2C[i2c_num]->int_clr.rx_fifo_full = 1;
- } else {
- // add check for unexcepted situations caused by noise.
- if (p_i2c->status != I2C_STATUS_ACK_ERROR && p_i2c->status != I2C_STATUS_IDLE) {
- i2c_master_cmd_begin_static(i2c_num);
- }
- }
- } else if (status & I2C_MASTER_TRAN_COMP_INT_ST_M) {
- I2C[i2c_num]->int_clr.master_tran_comp = 1;
- } else if (status & I2C_ARBITRATION_LOST_INT_ST_M) {
- I2C[i2c_num]->int_clr.arbitration_lost = 1;
- p_i2c_obj[i2c_num]->status = I2C_STATUS_TIMEOUT;
- i2c_master_cmd_begin_static(i2c_num);
- } else if (status & I2C_SLAVE_TRAN_COMP_INT_ST_M) {
- I2C[i2c_num]->int_clr.slave_tran_comp = 1;
- } else if (status & I2C_END_DETECT_INT_ST_M) {
- I2C[i2c_num]->int_ena.end_detect = 0;
- I2C[i2c_num]->int_clr.end_detect = 1;
- i2c_master_cmd_begin_static(i2c_num);
- } else if (status & I2C_RXFIFO_OVF_INT_ST_M) {
- I2C[i2c_num]->int_clr.rx_fifo_ovf = 1;
- } else if (status & I2C_TXFIFO_EMPTY_INT_ST_M) {
- int tx_fifo_rem = I2C_FIFO_LEN - I2C[i2c_num]->status_reg.tx_fifo_cnt;
- size_t size = 0;
- uint8_t *data = (uint8_t*) xRingbufferReceiveUpToFromISR(p_i2c->tx_ring_buf, &size, tx_fifo_rem);
- if (data) {
- for (idx = 0; idx < size; idx++) {
- WRITE_PERI_REG(I2C_DATA_APB_REG(i2c_num), data[idx]);
- }
- vRingbufferReturnItemFromISR(p_i2c->tx_ring_buf, data, &HPTaskAwoken);
- I2C[i2c_num]->int_ena.tx_fifo_empty = 1;
- I2C[i2c_num]->int_clr.tx_fifo_empty = 1;
- } else {
- I2C[i2c_num]->int_ena.tx_fifo_empty = 0;
- I2C[i2c_num]->int_clr.tx_fifo_empty = 1;
- }
- } else if (status & I2C_RXFIFO_FULL_INT_ST_M) {
- int rx_fifo_cnt = I2C[i2c_num]->status_reg.rx_fifo_cnt;
- for (idx = 0; idx < rx_fifo_cnt; idx++) {
- p_i2c->data_buf[idx] = I2C[i2c_num]->fifo_data.data;
- }
- xRingbufferSendFromISR(p_i2c->rx_ring_buf, p_i2c->data_buf, rx_fifo_cnt, &HPTaskAwoken);
- I2C[i2c_num]->int_clr.rx_fifo_full = 1;
- } else {
- I2C[i2c_num]->int_clr.val = status;
- }
- }
- if (p_i2c->mode == I2C_MODE_MASTER) {
- i2c_cmd_evt_t evt;
- evt.type = I2C_CMD_EVT_ALIVE;
- xQueueSendFromISR(p_i2c->cmd_evt_queue, &evt, &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_set_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t tx_trans_mode, i2c_trans_mode_t rx_trans_mode)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(tx_trans_mode < I2C_DATA_MODE_MAX, I2C_TRANS_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(rx_trans_mode < I2C_DATA_MODE_MAX, I2C_TRANS_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- I2C[i2c_num]->ctr.rx_lsb_first = rx_trans_mode; //set rx data msb first
- I2C[i2c_num]->ctr.tx_lsb_first = tx_trans_mode; //set tx data msb first
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-esp_err_t i2c_get_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t *tx_trans_mode, i2c_trans_mode_t *rx_trans_mode)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- if (tx_trans_mode) {
- *tx_trans_mode = I2C[i2c_num]->ctr.tx_lsb_first;
- }
- if (rx_trans_mode) {
- *rx_trans_mode = I2C[i2c_num]->ctr.rx_lsb_first;
- }
- return ESP_OK;
-}
-
-/* Some slave device will die by accident and keep the SDA in low level,
- * in this case, master should send several clock to make the slave release the bus.
- * Slave mode of ESP32 might also get in wrong state that held the SDA low,
- * in this case, master device could send a stop signal to make esp32 slave release the bus.
- **/
-static esp_err_t i2c_master_clear_bus(i2c_port_t i2c_num)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- int sda_in_sig = 0, scl_in_sig = 0;
- if (i2c_num == I2C_NUM_0) {
- sda_in_sig = I2CEXT0_SDA_IN_IDX;
- scl_in_sig = I2CEXT0_SCL_IN_IDX;
- } else if (i2c_num == I2C_NUM_1) {
- sda_in_sig = I2CEXT1_SDA_IN_IDX;
- scl_in_sig = I2CEXT1_SCL_IN_IDX;
- }
- int scl_io = GPIO.func_in_sel_cfg[scl_in_sig].func_sel;
- int sda_io = GPIO.func_in_sel_cfg[sda_in_sig].func_sel;
- I2C_CHECK((GPIO_IS_VALID_OUTPUT_GPIO(scl_io)), I2C_SCL_IO_ERR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK((GPIO_IS_VALID_GPIO(sda_io)), I2C_SDA_IO_ERR_STR, ESP_ERR_INVALID_ARG);
- // We do not check whether the SDA line is low
- // because after some serious interference, the bus may keep high all the time and the i2c bus is out of service.
- gpio_set_direction(scl_io, GPIO_MODE_OUTPUT_OD);
- gpio_set_direction(sda_io, GPIO_MODE_OUTPUT_OD);
- gpio_set_level(scl_io, 1);
- gpio_set_level(sda_io, 1);
- gpio_set_level(sda_io, 0);
- for (int i = 0; i < 9; i++) {
- gpio_set_level(scl_io, 0);
- gpio_set_level(scl_io, 1);
- }
- gpio_set_level(sda_io, 1);
- i2c_set_pin(i2c_num, sda_io, scl_io, 1, 1, I2C_MODE_MASTER);
- return ESP_OK;
-}
-
-/**if the power and SDA/SCL wires are in proper condition, everything works find with reading the slave.
- * If we remove the power supply for the slave during I2C is reading, or directly connect SDA or SCL to ground,
- * this would cause the I2C FSM get stuck in wrong state, all we can do is to reset the I2C hardware in this case.
- **/
-static esp_err_t i2c_hw_fsm_reset(i2c_port_t i2c_num)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- uint32_t ctr = I2C[i2c_num]->ctr.val;
- uint32_t fifo_conf = I2C[i2c_num]->fifo_conf.val;
- uint32_t scl_low_period = I2C[i2c_num]->scl_low_period.val;
- uint32_t scl_high_period = I2C[i2c_num]->scl_high_period.val;
- uint32_t scl_start_hold = I2C[i2c_num]->scl_start_hold.val;
- uint32_t scl_rstart_setup = I2C[i2c_num]->scl_rstart_setup.val;
- uint32_t scl_stop_hold = I2C[i2c_num]->scl_stop_hold.val;
- uint32_t scl_stop_setup = I2C[i2c_num]->scl_stop_setup.val;
- uint32_t sda_hold = I2C[i2c_num]->sda_hold.val;
- uint32_t sda_sample = I2C[i2c_num]->sda_sample.val;
- uint32_t timeout = I2C[i2c_num]->timeout.val;
- uint32_t scl_filter_cfg = I2C[i2c_num]->scl_filter_cfg.val;
- uint32_t sda_filter_cfg = I2C[i2c_num]->sda_filter_cfg.val;
- uint32_t slave_addr = I2C[i2c_num]->slave_addr.val;
-
- //to reset the I2C hw module, we need re-enable the hw
- i2c_hw_disable(i2c_num);
- i2c_master_clear_bus(i2c_num);
- i2c_hw_enable(i2c_num);
- I2C[i2c_num]->int_ena.val = 0;
- I2C[i2c_num]->ctr.val = ctr & (~I2C_TRANS_START_M);
- I2C[i2c_num]->fifo_conf.val = fifo_conf;
- I2C[i2c_num]->scl_low_period.val = scl_low_period;
- I2C[i2c_num]->scl_high_period.val = scl_high_period;
- I2C[i2c_num]->scl_start_hold.val = scl_start_hold;
- I2C[i2c_num]->scl_rstart_setup.val = scl_rstart_setup;
- I2C[i2c_num]->scl_stop_hold.val = scl_stop_hold;
- I2C[i2c_num]->scl_stop_setup.val = scl_stop_setup;
- I2C[i2c_num]->sda_hold.val = sda_hold;
- I2C[i2c_num]->sda_sample.val = sda_sample;
- I2C[i2c_num]->timeout.val = timeout;
- I2C[i2c_num]->scl_filter_cfg.val = scl_filter_cfg;
- I2C[i2c_num]->sda_filter_cfg.val = sda_filter_cfg;
- uint32_t intr_mask = ( I2C_TRANS_COMPLETE_INT_ENA_M
- | I2C_TRANS_START_INT_ENA_M
- | I2C_ACK_ERR_INT_ENA_M
- | I2C_RXFIFO_OVF_INT_ENA_M
- | I2C_SLAVE_TRAN_COMP_INT_ENA_M
- | I2C_TIME_OUT_INT_ENA_M);
- if (I2C[i2c_num]->ctr.ms_mode == I2C_MODE_SLAVE) {
- I2C[i2c_num]->slave_addr.val = slave_addr;
- intr_mask |= ( I2C_RXFIFO_FULL_INT_ENA_M | I2C_TRANS_COMPLETE_INT_ENA_M);
- } else {
- intr_mask |= I2C_ARBITRATION_LOST_INT_ENA_M;
- }
- I2C[i2c_num]->int_clr.val = intr_mask;
- I2C[i2c_num]->int_ena.val = intr_mask;
- return ESP_OK;
-}
-
-esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t* i2c_conf)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(i2c_conf != NULL, I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(i2c_conf->mode < I2C_MODE_MAX, I2C_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
-
- esp_err_t ret = i2c_set_pin(i2c_num, i2c_conf->sda_io_num, i2c_conf->scl_io_num,
- i2c_conf->sda_pullup_en, i2c_conf->scl_pullup_en, i2c_conf->mode);
- if (ret != ESP_OK) {
- return ret;
- }
- // Reset the I2C hardware in case there is a soft reboot.
- i2c_hw_disable(i2c_num);
- i2c_hw_enable(i2c_num);
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- I2C[i2c_num]->ctr.rx_lsb_first = I2C_DATA_MODE_MSB_FIRST; //set rx data msb first
- I2C[i2c_num]->ctr.tx_lsb_first = I2C_DATA_MODE_MSB_FIRST; //set tx data msb first
- I2C[i2c_num]->ctr.ms_mode = i2c_conf->mode; //mode for master or slave
- I2C[i2c_num]->ctr.sda_force_out = 1; // set open-drain output mode
- I2C[i2c_num]->ctr.scl_force_out = 1; // set open-drain output mode
- I2C[i2c_num]->ctr.sample_scl_level = 0; //sample at high level of clock
-
- if (i2c_conf->mode == I2C_MODE_SLAVE) { //slave mode
- I2C[i2c_num]->slave_addr.addr = i2c_conf->slave.slave_addr;
- I2C[i2c_num]->slave_addr.en_10bit = i2c_conf->slave.addr_10bit_en;
- I2C[i2c_num]->fifo_conf.nonfifo_en = 0;
- I2C[i2c_num]->fifo_conf.fifo_addr_cfg_en = 0;
- I2C[i2c_num]->fifo_conf.rx_fifo_full_thrhd = I2C_FIFO_FULL_THRESH_VAL;
- I2C[i2c_num]->fifo_conf.tx_fifo_empty_thrhd = I2C_FIFO_EMPTY_THRESH_VAL;
- I2C[i2c_num]->ctr.trans_start = 0;
- I2C[i2c_num]->timeout.tout = I2C_SLAVE_TIMEOUT_DEFAULT;
- //set timing for data
- I2C[i2c_num]->sda_hold.time = I2C_SLAVE_SDA_HOLD_DEFAULT;
- I2C[i2c_num]->sda_sample.time = I2C_SLAVE_SDA_SAMPLE_DEFAULT;
- } else {
- I2C[i2c_num]->fifo_conf.nonfifo_en = 0;
- int cycle = (I2C_APB_CLK_FREQ / i2c_conf->master.clk_speed);
- int half_cycle = cycle / 2;
- I2C[i2c_num]->timeout.tout = cycle * I2C_MASTER_TOUT_CNUM_DEFAULT;
- //set timing for data
- I2C[i2c_num]->sda_hold.time = half_cycle / 2;
- I2C[i2c_num]->sda_sample.time = half_cycle / 2;
-
- I2C[i2c_num]->scl_low_period.period = half_cycle;
- I2C[i2c_num]->scl_high_period.period = half_cycle;
- //set timing for start signal
- I2C[i2c_num]->scl_start_hold.time = half_cycle;
- I2C[i2c_num]->scl_rstart_setup.time = half_cycle;
- //set timing for stop signal
- I2C[i2c_num]->scl_stop_hold.time = half_cycle;
- I2C[i2c_num]->scl_stop_setup.time = half_cycle;
- }
-
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-esp_err_t i2c_set_period(i2c_port_t i2c_num, int high_period, int low_period)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK((high_period <= I2C_SCL_HIGH_PERIOD_V) && (high_period > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK((low_period <= I2C_SCL_LOW_PERIOD_V) && (low_period > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
-
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- I2C[i2c_num]->scl_high_period.period = high_period;
- I2C[i2c_num]->scl_low_period.period = low_period;
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-esp_err_t i2c_get_period(i2c_port_t i2c_num, int* high_period, int* low_period)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- if (high_period) {
- *high_period = I2C[i2c_num]->scl_high_period.period;
- }
- if (low_period) {
- *low_period = I2C[i2c_num]->scl_low_period.period;
- }
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-esp_err_t i2c_set_start_timing(i2c_port_t i2c_num, int setup_time, int hold_time)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK((hold_time <= I2C_SCL_START_HOLD_TIME_V) && (hold_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK((setup_time <= I2C_SCL_RSTART_SETUP_TIME_V) && (setup_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
-
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- I2C[i2c_num]->scl_start_hold.time = hold_time;
- I2C[i2c_num]->scl_rstart_setup.time = setup_time;
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-esp_err_t i2c_get_start_timing(i2c_port_t i2c_num, int* setup_time, int* hold_time)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- if (hold_time) {
- *hold_time = I2C[i2c_num]->scl_start_hold.time;
- }
- if (setup_time) {
- *setup_time = I2C[i2c_num]->scl_rstart_setup.time;
- }
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-esp_err_t i2c_set_stop_timing(i2c_port_t i2c_num, int setup_time, int hold_time)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK((setup_time <= I2C_SCL_STOP_SETUP_TIME_V) && (setup_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK((hold_time <= I2C_SCL_STOP_HOLD_TIME_V) && (hold_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
-
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- I2C[i2c_num]->scl_stop_hold.time = hold_time;
- I2C[i2c_num]->scl_stop_setup.time = setup_time;
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-esp_err_t i2c_get_stop_timing(i2c_port_t i2c_num, int* setup_time, int* hold_time)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- if (setup_time) {
- *setup_time = I2C[i2c_num]->scl_stop_setup.time;
- }
- if (hold_time) {
- *hold_time = I2C[i2c_num]->scl_stop_hold.time;
- }
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-esp_err_t i2c_set_data_timing(i2c_port_t i2c_num, int sample_time, int hold_time)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK((sample_time <= I2C_SDA_SAMPLE_TIME_V) && (sample_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK((hold_time <= I2C_SDA_HOLD_TIME_V) && (hold_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
-
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- I2C[i2c_num]->sda_hold.time = hold_time;
- I2C[i2c_num]->sda_sample.time = sample_time;
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-esp_err_t i2c_get_data_timing(i2c_port_t i2c_num, int* sample_time, int* hold_time)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- if (sample_time) {
- *sample_time = I2C[i2c_num]->sda_sample.time;
- }
- if (hold_time) {
- *hold_time = I2C[i2c_num]->sda_hold.time;
- }
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-esp_err_t i2c_set_timeout(i2c_port_t i2c_num, int timeout)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK((timeout <= I2C_TIME_OUT_REG_V) && (timeout > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
-
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- I2C[i2c_num]->timeout.tout = timeout;
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- return ESP_OK;
-}
-
-esp_err_t i2c_get_timeout(i2c_port_t i2c_num, int* timeout)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- if (timeout) {
- *timeout = I2C[i2c_num]->timeout.tout;
- }
- return ESP_OK;
-}
-
-esp_err_t i2c_isr_register(i2c_port_t i2c_num, void (*fn)(void*), void * arg, int intr_alloc_flags, intr_handle_t *handle)
-{
- I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(fn != NULL, I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
- esp_err_t ret;
- switch (i2c_num) {
- case I2C_NUM_1:
- ret = esp_intr_alloc(ETS_I2C_EXT1_INTR_SOURCE, intr_alloc_flags, fn, arg, handle);
- break;
- case I2C_NUM_0:
- default:
- ret = esp_intr_alloc(ETS_I2C_EXT0_INTR_SOURCE, intr_alloc_flags, fn, arg, handle);
- break;
- }
- return ret;
-}
-
-esp_err_t i2c_isr_free(intr_handle_t handle)
-{
- return esp_intr_free(handle);
-}
-
-esp_err_t i2c_set_pin(i2c_port_t i2c_num, int sda_io_num, int scl_io_num, gpio_pullup_t sda_pullup_en, gpio_pullup_t scl_pullup_en, i2c_mode_t mode)
-{
- I2C_CHECK(( i2c_num < I2C_NUM_MAX ), I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(((sda_io_num < 0) || ((GPIO_IS_VALID_OUTPUT_GPIO(sda_io_num)))), I2C_SDA_IO_ERR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(scl_io_num < 0 ||
- (GPIO_IS_VALID_OUTPUT_GPIO(scl_io_num)) ||
- (GPIO_IS_VALID_GPIO(scl_io_num) && mode == I2C_MODE_SLAVE),
- I2C_SCL_IO_ERR_STR,
- ESP_ERR_INVALID_ARG);
- I2C_CHECK(sda_io_num < 0 ||
- (sda_pullup_en == GPIO_PULLUP_ENABLE && GPIO_IS_VALID_OUTPUT_GPIO(sda_io_num)) ||
- sda_pullup_en == GPIO_PULLUP_DISABLE, I2C_GPIO_PULLUP_ERR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(scl_io_num < 0 ||
- (scl_pullup_en == GPIO_PULLUP_ENABLE && GPIO_IS_VALID_OUTPUT_GPIO(scl_io_num)) ||
- scl_pullup_en == GPIO_PULLUP_DISABLE, I2C_GPIO_PULLUP_ERR_STR, ESP_ERR_INVALID_ARG);
-
- int sda_in_sig, sda_out_sig, scl_in_sig, scl_out_sig;
- switch (i2c_num) {
- case I2C_NUM_1:
- sda_out_sig = I2CEXT1_SDA_OUT_IDX;
- sda_in_sig = I2CEXT1_SDA_IN_IDX;
- scl_out_sig = I2CEXT1_SCL_OUT_IDX;
- scl_in_sig = I2CEXT1_SCL_IN_IDX;
- break;
- case I2C_NUM_0:
- default:
- sda_out_sig = I2CEXT0_SDA_OUT_IDX;
- sda_in_sig = I2CEXT0_SDA_IN_IDX;
- scl_out_sig = I2CEXT0_SCL_OUT_IDX;
- scl_in_sig = I2CEXT0_SCL_IN_IDX;
- break;
- }
- if (sda_io_num >= 0) {
- gpio_set_level(sda_io_num, I2C_IO_INIT_LEVEL);
- PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[sda_io_num], PIN_FUNC_GPIO);
- gpio_set_direction(sda_io_num, GPIO_MODE_INPUT_OUTPUT_OD);
-
- if (sda_pullup_en == GPIO_PULLUP_ENABLE) {
- gpio_set_pull_mode(sda_io_num, GPIO_PULLUP_ONLY);
- } else {
- gpio_set_pull_mode(sda_io_num, GPIO_FLOATING);
- }
- gpio_matrix_out(sda_io_num, sda_out_sig, 0, 0);
- gpio_matrix_in(sda_io_num, sda_in_sig, 0);
- }
-
- if (scl_io_num >= 0) {
- gpio_set_level(scl_io_num, I2C_IO_INIT_LEVEL);
- PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[scl_io_num], PIN_FUNC_GPIO);
- if (mode == I2C_MODE_MASTER) {
- gpio_set_direction(scl_io_num, GPIO_MODE_INPUT_OUTPUT_OD);
- gpio_matrix_out(scl_io_num, scl_out_sig, 0, 0);
- } else {
- gpio_set_direction(scl_io_num, GPIO_MODE_INPUT);
- }
- if (scl_pullup_en == GPIO_PULLUP_ENABLE) {
- gpio_set_pull_mode(scl_io_num, GPIO_PULLUP_ONLY);
- } else {
- gpio_set_pull_mode(scl_io_num, GPIO_FLOATING);
- }
- gpio_matrix_in(scl_io_num, scl_in_sig, 0);
- }
- return ESP_OK;
-}
-
-i2c_cmd_handle_t i2c_cmd_link_create()
-{
-#if !CONFIG_SPIRAM_USE_MALLOC
- i2c_cmd_desc_t* cmd_desc = (i2c_cmd_desc_t*) calloc(1, sizeof(i2c_cmd_desc_t));
-#else
- i2c_cmd_desc_t* cmd_desc = (i2c_cmd_desc_t*) heap_caps_calloc(1, sizeof(i2c_cmd_desc_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
-#endif
- return (i2c_cmd_handle_t) cmd_desc;
-}
-
-void i2c_cmd_link_delete(i2c_cmd_handle_t cmd_handle)
-{
- if (cmd_handle == NULL) {
- return;
- }
- i2c_cmd_desc_t* cmd = (i2c_cmd_desc_t*) cmd_handle;
- while (cmd->free) {
- i2c_cmd_link_t* ptmp = cmd->free;
- cmd->free = cmd->free->next;
- free(ptmp);
- }
- cmd->cur = NULL;
- cmd->free = NULL;
- cmd->head = NULL;
- free(cmd_handle);
- return;
-}
-
-static esp_err_t i2c_cmd_link_append(i2c_cmd_handle_t cmd_handle, i2c_cmd_t* cmd)
-{
- i2c_cmd_desc_t* cmd_desc = (i2c_cmd_desc_t*) cmd_handle;
- if (cmd_desc->head == NULL) {
-#if !CONFIG_SPIRAM_USE_MALLOC
- cmd_desc->head = (i2c_cmd_link_t*) calloc(1, sizeof(i2c_cmd_link_t));
-#else
- cmd_desc->head = (i2c_cmd_link_t*) heap_caps_calloc(1, sizeof(i2c_cmd_link_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
-#endif
- if (cmd_desc->head == NULL) {
- ESP_LOGE(I2C_TAG, I2C_CMD_MALLOC_ERR_STR);
- goto err;
- }
- cmd_desc->cur = cmd_desc->head;
- cmd_desc->free = cmd_desc->head;
- } else {
-#if !CONFIG_SPIRAM_USE_MALLOC
- cmd_desc->cur->next = (i2c_cmd_link_t*) calloc(1, sizeof(i2c_cmd_link_t));
-#else
- cmd_desc->cur->next = (i2c_cmd_link_t*) heap_caps_calloc(1, sizeof(i2c_cmd_link_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
-#endif
- if (cmd_desc->cur->next == NULL) {
- ESP_LOGE(I2C_TAG, I2C_CMD_MALLOC_ERR_STR);
- goto err;
- }
- cmd_desc->cur = cmd_desc->cur->next;
- }
- memcpy((uint8_t*) &cmd_desc->cur->cmd, (uint8_t*) cmd, sizeof(i2c_cmd_t));
- cmd_desc->cur->next = NULL;
- return ESP_OK;
-
- err:
- return ESP_FAIL;
-}
-
-esp_err_t i2c_master_start(i2c_cmd_handle_t cmd_handle)
-{
- I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
- i2c_cmd_t cmd;
- cmd.ack_en = 0;
- cmd.ack_exp = 0;
- cmd.ack_val = 0;
- cmd.byte_num = 0;
- cmd.data = NULL;
- cmd.op_code = I2C_CMD_RESTART;
- return i2c_cmd_link_append(cmd_handle, &cmd);
-}
-
-esp_err_t i2c_master_stop(i2c_cmd_handle_t cmd_handle)
-{
- I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
- i2c_cmd_t cmd;
- cmd.ack_en = 0;
- cmd.ack_exp = 0;
- cmd.ack_val = 0;
- cmd.byte_num = 0;
- cmd.data = NULL;
- cmd.op_code = I2C_CMD_STOP;
- return i2c_cmd_link_append(cmd_handle, &cmd);
-}
-
-esp_err_t i2c_master_write(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t data_len, bool ack_en)
-{
- I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
-
- uint8_t len_tmp;
- int data_offset = 0;
- esp_err_t ret;
- while (data_len > 0) {
- len_tmp = data_len > 0xff ? 0xff : data_len;
- data_len -= len_tmp;
- i2c_cmd_t cmd;
- cmd.ack_en = ack_en;
- cmd.ack_exp = 0;
- cmd.ack_val = 0;
- cmd.byte_num = len_tmp;
- cmd.op_code = I2C_CMD_WRITE;
- cmd.data = data + data_offset;
- ret = i2c_cmd_link_append(cmd_handle, &cmd);
- data_offset += len_tmp;
- if (ret != ESP_OK) {
- return ret;
- }
- }
- return ESP_OK;
-}
-
-esp_err_t i2c_master_write_byte(i2c_cmd_handle_t cmd_handle, uint8_t data, bool ack_en)
-{
- I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
- i2c_cmd_t cmd;
- cmd.ack_en = ack_en;
- cmd.ack_exp = 0;
- cmd.ack_val = 0;
- cmd.byte_num = 1;
- cmd.op_code = I2C_CMD_WRITE;
- cmd.data = NULL;
- cmd.byte_cmd = data;
- return i2c_cmd_link_append(cmd_handle, &cmd);
-}
-
-static esp_err_t i2c_master_read_static(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t data_len, i2c_ack_type_t ack)
-{
- int len_tmp;
- int data_offset = 0;
- esp_err_t ret;
- while (data_len > 0) {
- len_tmp = data_len > 0xff ? 0xff : data_len;
- data_len -= len_tmp;
- i2c_cmd_t cmd;
- cmd.ack_en = 0;
- cmd.ack_exp = 0;
- cmd.ack_val = ack & 0x1;
- cmd.byte_num = len_tmp;
- cmd.op_code = I2C_CMD_READ;
- cmd.data = data + data_offset;
- ret = i2c_cmd_link_append(cmd_handle, &cmd);
- data_offset += len_tmp;
- if (ret != ESP_OK) {
- return ret;
- }
- }
- return ESP_OK;
-}
-
-esp_err_t i2c_master_read_byte(i2c_cmd_handle_t cmd_handle, uint8_t* data, i2c_ack_type_t ack)
-{
- I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(ack < I2C_MASTER_ACK_MAX, I2C_ACK_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
-
- i2c_cmd_t cmd;
- cmd.ack_en = 0;
- cmd.ack_exp = 0;
- cmd.ack_val = ((ack == I2C_MASTER_LAST_NACK) ? I2C_MASTER_NACK : (ack & 0x1));
- cmd.byte_num = 1;
- cmd.op_code = I2C_CMD_READ;
- cmd.data = data;
- return i2c_cmd_link_append(cmd_handle, &cmd);
-}
-
-esp_err_t i2c_master_read(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t data_len, i2c_ack_type_t ack)
-{
- I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(ack < I2C_MASTER_ACK_MAX, I2C_ACK_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(data_len > 0, I2C_DATA_LEN_ERR_STR, ESP_ERR_INVALID_ARG);
-
- if(ack != I2C_MASTER_LAST_NACK) {
- return i2c_master_read_static(cmd_handle, data, data_len, ack);
- } else {
- if(data_len == 1) {
- return i2c_master_read_byte(cmd_handle, data, I2C_MASTER_NACK);
- } else {
- esp_err_t ret;
- if((ret = i2c_master_read_static(cmd_handle, data, data_len - 1, I2C_MASTER_ACK)) != ESP_OK) {
- return ret;
- }
- return i2c_master_read_byte(cmd_handle, data + data_len - 1, I2C_MASTER_NACK);
- }
- }
-}
-
-static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num)
-{
- i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
- portBASE_TYPE HPTaskAwoken = pdFALSE;
- i2c_cmd_evt_t evt;
- //This should never happen
- if (p_i2c->mode == I2C_MODE_SLAVE) {
- return;
- }
- if (p_i2c->status == I2C_STATUS_DONE) {
- return;
- } else if ((p_i2c->status == I2C_STATUS_ACK_ERROR)
- || (p_i2c->status == I2C_STATUS_TIMEOUT)) {
- I2C[i2c_num]->int_ena.end_detect = 0;
- I2C[i2c_num]->int_clr.end_detect = 1;
- if(p_i2c->status == I2C_STATUS_TIMEOUT) {
- I2C[i2c_num]->int_clr.time_out = 1;
- I2C[i2c_num]->int_ena.val = 0;
- }
- evt.type = I2C_CMD_EVT_DONE;
- xQueueOverwriteFromISR(p_i2c->cmd_evt_queue, &evt, &HPTaskAwoken);
- if (HPTaskAwoken == pdTRUE) {
- portYIELD_FROM_ISR();
- }
- return;
- } else if (p_i2c->cmd_link.head != NULL && p_i2c->status == I2C_STATUS_READ) {
- i2c_cmd_t *cmd = &p_i2c->cmd_link.head->cmd;
- while (p_i2c->rx_cnt-- > 0) {
- *cmd->data++ = READ_PERI_REG(I2C_DATA_APB_REG(i2c_num));
- }
- if (cmd->byte_num > 0) {
- p_i2c->rx_fifo_remain = I2C_FIFO_LEN;
- p_i2c->cmd_idx = 0;
- } else {
- p_i2c->cmd_link.head = p_i2c->cmd_link.head->next;
- }
- }
- if (p_i2c->cmd_link.head == NULL) {
- p_i2c->cmd_link.cur = NULL;
- evt.type = I2C_CMD_EVT_DONE;
- xQueueOverwriteFromISR(p_i2c->cmd_evt_queue, &evt, &HPTaskAwoken);
- if (HPTaskAwoken == pdTRUE) {
- portYIELD_FROM_ISR();
- }
- // Return to the IDLE status after cmd_eve_done signal were send out.
- p_i2c->status = I2C_STATUS_IDLE;
- return;
- }
- while (p_i2c->cmd_link.head) {
- i2c_cmd_t *cmd = &p_i2c->cmd_link.head->cmd;
- I2C[i2c_num]->command[p_i2c->cmd_idx].val = 0;
- I2C[i2c_num]->command[p_i2c->cmd_idx].ack_en = cmd->ack_en;
- I2C[i2c_num]->command[p_i2c->cmd_idx].ack_exp = cmd->ack_exp;
- I2C[i2c_num]->command[p_i2c->cmd_idx].ack_val = cmd->ack_val;
- I2C[i2c_num]->command[p_i2c->cmd_idx].byte_num = cmd->byte_num;
- I2C[i2c_num]->command[p_i2c->cmd_idx].op_code = cmd->op_code;
- if (cmd->op_code == I2C_CMD_WRITE) {
- uint32_t wr_filled = 0;
- //TODO: to reduce interrupt number
- if (cmd->data) {
- while (p_i2c->tx_fifo_remain > 0 && cmd->byte_num > 0) {
- WRITE_PERI_REG(I2C_DATA_APB_REG(i2c_num), *cmd->data++);
- p_i2c->tx_fifo_remain--;
- cmd->byte_num--;
- wr_filled++;
- }
- } else {
- WRITE_PERI_REG(I2C_DATA_APB_REG(i2c_num), cmd->byte_cmd);
- p_i2c->tx_fifo_remain--;
- cmd->byte_num--;
- wr_filled ++;
- }
- //Workaround for register field operation.
- I2C[i2c_num]->command[p_i2c->cmd_idx].byte_num = wr_filled;
- I2C[i2c_num]->command[p_i2c->cmd_idx + 1].val = 0;
- I2C[i2c_num]->command[p_i2c->cmd_idx + 1].op_code = I2C_CMD_END;
- p_i2c->tx_fifo_remain = I2C_FIFO_LEN;
- p_i2c->cmd_idx = 0;
- if (cmd->byte_num > 0) {
- } else {
- p_i2c->cmd_link.head = p_i2c->cmd_link.head->next;
- }
- p_i2c->status = I2C_STATUS_WRITE;
- break;
- } else if(cmd->op_code == I2C_CMD_READ) {
- //TODO: to reduce interrupt number
- p_i2c->rx_cnt = cmd->byte_num > p_i2c->rx_fifo_remain ? p_i2c->rx_fifo_remain : cmd->byte_num;
- cmd->byte_num -= p_i2c->rx_cnt;
- I2C[i2c_num]->command[p_i2c->cmd_idx].byte_num = p_i2c->rx_cnt;
- I2C[i2c_num]->command[p_i2c->cmd_idx].ack_val = cmd->ack_val;
- I2C[i2c_num]->command[p_i2c->cmd_idx + 1].val = 0;
- I2C[i2c_num]->command[p_i2c->cmd_idx + 1].op_code = I2C_CMD_END;
- p_i2c->status = I2C_STATUS_READ;
- break;
- } else {
- }
- p_i2c->cmd_idx++;
- p_i2c->cmd_link.head = p_i2c->cmd_link.head->next;
- if (p_i2c->cmd_link.head == NULL || p_i2c->cmd_idx >= 15) {
- p_i2c->tx_fifo_remain = I2C_FIFO_LEN;
- p_i2c->cmd_idx = 0;
- break;
- }
- }
- I2C[i2c_num]->int_clr.end_detect = 1;
- I2C[i2c_num]->int_ena.end_detect = 1;
- I2C[i2c_num]->ctr.trans_start = 0;
- I2C[i2c_num]->ctr.trans_start = 1;
- return;
-}
-
-#if CONFIG_SPIRAM_USE_MALLOC
-//Check whether read or write buffer in cmd_link is internal.
-static bool is_cmd_link_buffer_internal(i2c_cmd_link_t *link)
-{
- i2c_cmd_link_t* cmd_link = link;
- while(cmd_link != NULL) {
- if (cmd_link->cmd.op_code == I2C_CMD_WRITE || cmd_link->cmd.op_code == I2C_CMD_READ) {
- if( cmd_link->cmd.data != NULL && !esp_ptr_internal(cmd_link->cmd.data)) {
- return false;
- }
- }
- cmd_link = cmd_link->next;
- }
- return true;
-}
-#endif
-
-esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle, TickType_t ticks_to_wait)
-{
- I2C_CHECK(( i2c_num < I2C_NUM_MAX ), I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
- I2C_CHECK(p_i2c_obj[i2c_num] != NULL, I2C_DRIVER_NOT_INSTALL_ERR_STR, ESP_ERR_INVALID_STATE);
- I2C_CHECK(p_i2c_obj[i2c_num]->mode == I2C_MODE_MASTER, I2C_MASTER_MODE_ERR_STR, ESP_ERR_INVALID_STATE);
- I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
-
-#if CONFIG_SPIRAM_USE_MALLOC
- //If the i2c read or write buffer is not in internal RAM, we will return ESP_FAIL
- //to avoid the ISR handler function crashing when the cache is disabled.
- if( (p_i2c_obj[i2c_num]->intr_alloc_flags & ESP_INTR_FLAG_IRAM) ) {
- if( !is_cmd_link_buffer_internal(((i2c_cmd_desc_t*)cmd_handle)->head) ) {
- ESP_LOGE(I2C_TAG, I2C_PSRAM_BUFFER_WARN_STR);
- return ESP_ERR_INVALID_ARG;
- }
- }
-#endif
- // Sometimes when the FSM get stuck, the ACK_ERR interrupt will occur endlessly until we reset the FSM and clear bus.
- static uint8_t clear_bus_cnt = 0;
- esp_err_t ret = ESP_FAIL;
- i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
- portTickType ticks_start = xTaskGetTickCount();
- portBASE_TYPE res = xSemaphoreTake(p_i2c->cmd_mux, ticks_to_wait);
- if (res == pdFALSE) {
- return ESP_ERR_TIMEOUT;
- }
- xQueueReset(p_i2c->cmd_evt_queue);
- if (p_i2c->status == I2C_STATUS_TIMEOUT
- || I2C[i2c_num]->status_reg.bus_busy == 1) {
- i2c_hw_fsm_reset(i2c_num);
- clear_bus_cnt = 0;
- }
- i2c_reset_tx_fifo(i2c_num);
- i2c_reset_rx_fifo(i2c_num);
- i2c_cmd_desc_t* cmd = (i2c_cmd_desc_t*) cmd_handle;
- p_i2c->cmd_link.free = cmd->free;
- p_i2c->cmd_link.cur = cmd->cur;
- p_i2c->cmd_link.head = cmd->head;
- p_i2c->status = I2C_STATUS_IDLE;
- p_i2c->cmd_idx = 0;
- p_i2c->rx_cnt = 0;
- p_i2c->tx_fifo_remain = I2C_FIFO_LEN;
- p_i2c->rx_fifo_remain = I2C_FIFO_LEN;
- i2c_reset_tx_fifo(i2c_num);
- i2c_reset_rx_fifo(i2c_num);
- // These two interrupts some times can not be cleared when the FSM gets stuck.
- // so we disable them when these two interrupt occurs and re-enable them here.
- I2C[i2c_num]->int_ena.ack_err = 1;
- I2C[i2c_num]->int_ena.time_out = 1;
- //start send commands, at most 32 bytes one time, isr handler will process the remaining commands.
- i2c_master_cmd_begin_static(i2c_num);
-
- // Wait event bits
- i2c_cmd_evt_t evt;
- while (1) {
- TickType_t wait_time = xTaskGetTickCount();
- if (wait_time - ticks_start > ticks_to_wait) { // out of time
- wait_time = I2C_CMD_ALIVE_INTERVAL_TICK;
- } else {
- wait_time = ticks_to_wait - (wait_time - ticks_start);
- if (wait_time < I2C_CMD_ALIVE_INTERVAL_TICK) {
- wait_time = I2C_CMD_ALIVE_INTERVAL_TICK;
- }
- }
- // In master mode, since we don't have an interrupt to detective bus error or FSM state, what we do here is to make
- // sure the interrupt mechanism for master mode is still working.
- // If the command sending is not finished and there is no interrupt any more, the bus is probably dead caused by external noise.
- portBASE_TYPE evt_res = xQueueReceive(p_i2c->cmd_evt_queue, &evt, wait_time);
- if (evt_res == pdTRUE) {
- if (evt.type == I2C_CMD_EVT_DONE) {
- if (p_i2c->status == I2C_STATUS_TIMEOUT) {
- // If the I2C slave are powered off or the SDA/SCL are connected to ground, for example,
- // I2C hw FSM would get stuck in wrong state, we have to reset the I2C module in this case.
- i2c_hw_fsm_reset(i2c_num);
- clear_bus_cnt = 0;
- ret = ESP_ERR_TIMEOUT;
- } else if (p_i2c->status == I2C_STATUS_ACK_ERROR) {
- clear_bus_cnt++;
- if(clear_bus_cnt >= I2C_ACKERR_CNT_MAX) {
- i2c_master_clear_bus(i2c_num);
- clear_bus_cnt = 0;
- }
- ret = ESP_FAIL;
- } else {
- ret = ESP_OK;
- }
- break;
- }
- if (evt.type == I2C_CMD_EVT_ALIVE) {
- }
- } else {
- ret = ESP_ERR_TIMEOUT;
- // If the I2C slave are powered off or the SDA/SCL are connected to ground, for example,
- // I2C hw FSM would get stuck in wrong state, we have to reset the I2C module in this case.
- i2c_hw_fsm_reset(i2c_num);
- clear_bus_cnt = 0;
- break;
- }
- }
- p_i2c->status = I2C_STATUS_DONE;
- xSemaphoreGive(p_i2c->cmd_mux);
- return ret;
-}
-
-int i2c_slave_write_buffer(i2c_port_t i2c_num, uint8_t* data, int size, TickType_t ticks_to_wait)
-{
- I2C_CHECK(( i2c_num < I2C_NUM_MAX ), I2C_NUM_ERROR_STR, ESP_FAIL);
- I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_FAIL);
- I2C_CHECK(p_i2c_obj[i2c_num]->mode == I2C_MODE_SLAVE, I2C_MODE_SLAVE_ERR_STR, ESP_FAIL);
- i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
-
- portBASE_TYPE res;
- int cnt = 0;
- portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait;
-
- res = xSemaphoreTake(p_i2c->slv_tx_mux, ticks_to_wait);
- if (res == pdFALSE) {
- return 0;
- }
- ticks_to_wait = ticks_end - xTaskGetTickCount();
- res = xRingbufferSend(p_i2c->tx_ring_buf, data, size, ticks_to_wait);
- if (res == pdFALSE) {
- cnt = 0;
- } else {
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- I2C[i2c_num]->int_clr.tx_fifo_empty = 1;
- I2C[i2c_num]->int_ena.tx_fifo_empty = 1;
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- cnt = size;
- }
- xSemaphoreGive(p_i2c->slv_tx_mux);
- return cnt;
-}
-
-static int i2c_slave_read(i2c_port_t i2c_num, uint8_t* data, size_t max_size, TickType_t ticks_to_wait)
-{
- i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
- size_t size = 0;
- uint8_t* pdata = (uint8_t*) xRingbufferReceiveUpTo(p_i2c->rx_ring_buf, &size, ticks_to_wait, max_size);
- if (pdata && size > 0) {
- memcpy(data, pdata, size);
- vRingbufferReturnItem(p_i2c->rx_ring_buf, pdata);
- }
- return size;
-}
-
-int i2c_slave_read_buffer(i2c_port_t i2c_num, uint8_t* data, size_t max_size, TickType_t ticks_to_wait)
-{
- I2C_CHECK(( i2c_num < I2C_NUM_MAX ), I2C_NUM_ERROR_STR, ESP_FAIL);
- I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_FAIL);
- I2C_CHECK(p_i2c_obj[i2c_num]->mode == I2C_MODE_SLAVE, I2C_MODE_SLAVE_ERR_STR, ESP_FAIL);
-
- i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
- portBASE_TYPE res;
- portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait;
- res = xSemaphoreTake(p_i2c->slv_rx_mux, ticks_to_wait);
- if (res == pdFALSE) {
- return 0;
- }
- ticks_to_wait = ticks_end - xTaskGetTickCount();
- int cnt = i2c_slave_read(i2c_num, data, max_size, ticks_to_wait);
- if (cnt > 0) {
- I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
- I2C[i2c_num]->int_ena.rx_fifo_full = 1;
- I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
- ticks_to_wait = ticks_end - xTaskGetTickCount();
- if (cnt < max_size && ticks_to_wait > 0) {
- cnt += i2c_slave_read(i2c_num, data + cnt, max_size - cnt, ticks_to_wait);
- }
- } else {
- cnt = 0;
- }
- xSemaphoreGive(p_i2c->slv_rx_mux);
- return cnt;
-}
+// Copyright 2015-2016 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.
+#include
+#include
+#include "esp_types.h"
+#include "esp_attr.h"
+#include "esp_intr.h"
+#include "esp_log.h"
+#include "malloc.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/semphr.h"
+#include "freertos/xtensa_api.h"
+#include "freertos/task.h"
+#include "freertos/ringbuf.h"
+#include "soc/dport_reg.h"
+#include "soc/i2c_struct.h"
+#include "soc/i2c_reg.h"
+#include "driver/i2c.h"
+#include "driver/gpio.h"
+#include "driver/periph_ctrl.h"
+
+static const char* I2C_TAG = "i2c";
+#define I2C_CHECK(a, str, ret) if(!(a)) { \
+ ESP_LOGE(I2C_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
+ return (ret); \
+ }
+
+static portMUX_TYPE i2c_spinlock[I2C_NUM_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED};
+/* DRAM_ATTR is required to avoid I2C array placed in flash, due to accessed from ISR */
+static DRAM_ATTR i2c_dev_t* const I2C[I2C_NUM_MAX] = { &I2C0, &I2C1 };
+
+#define I2C_ENTER_CRITICAL_ISR(mux) portENTER_CRITICAL_ISR(mux)
+#define I2C_EXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL_ISR(mux)
+#define I2C_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux)
+#define I2C_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux)
+
+#define I2C_DRIVER_ERR_STR "i2c driver install error"
+#define I2C_DRIVER_MALLOC_ERR_STR "i2c driver malloc error"
+#define I2C_NUM_ERROR_STR "i2c number error"
+#define I2C_TIMEING_VAL_ERR_STR "i2c timing value error"
+#define I2C_ADDR_ERROR_STR "i2c null address error"
+#define I2C_DRIVER_NOT_INSTALL_ERR_STR "i2c driver not installed"
+#define I2C_SLAVE_BUFFER_LEN_ERR_STR "i2c buffer size too small for slave mode"
+#define I2C_EVT_QUEUE_ERR_STR "i2c evt queue error"
+#define I2C_SEM_ERR_STR "i2c semaphore error"
+#define I2C_BUF_ERR_STR "i2c ringbuffer error"
+#define I2C_MASTER_MODE_ERR_STR "Only allowed in master mode"
+#define I2C_MODE_SLAVE_ERR_STR "Only allowed in slave mode"
+#define I2C_CMD_MALLOC_ERR_STR "i2c command link malloc error"
+#define I2C_TRANS_MODE_ERR_STR "i2c trans mode error"
+#define I2C_MODE_ERR_STR "i2c mode error"
+#define I2C_SDA_IO_ERR_STR "sda gpio number error"
+#define I2C_SCL_IO_ERR_STR "scl gpio number error"
+#define I2C_CMD_LINK_INIT_ERR_STR "i2c command link error"
+#define I2C_GPIO_PULLUP_ERR_STR "this i2c pin does not support internal pull-up"
+#define I2C_ACK_TYPE_ERR_STR "i2c ack type error"
+#define I2C_DATA_LEN_ERR_STR "i2c data read length error"
+#define I2C_PSRAM_BUFFER_WARN_STR "Using buffer allocated from psram"
+#define I2C_FIFO_FULL_THRESH_VAL (28)
+#define I2C_FIFO_EMPTY_THRESH_VAL (5)
+#define I2C_IO_INIT_LEVEL (1)
+#define I2C_CMD_ALIVE_INTERVAL_TICK (1000 / portTICK_PERIOD_MS)
+#define I2C_CMD_EVT_ALIVE (0)
+#define I2C_CMD_EVT_DONE (1)
+#define I2C_EVT_QUEUE_LEN (1)
+#define I2C_SLAVE_TIMEOUT_DEFAULT (32000) /* I2C slave timeout value, APB clock cycle number */
+#define I2C_SLAVE_SDA_SAMPLE_DEFAULT (10) /* I2C slave sample time after scl positive edge default value */
+#define I2C_SLAVE_SDA_HOLD_DEFAULT (10) /* I2C slave hold time after scl negative edge default value */
+#define I2C_MASTER_TOUT_CNUM_DEFAULT (8) /* I2C master timeout cycle number of I2C clock, after which the timeout interrupt will be triggered */
+#define I2C_ACKERR_CNT_MAX (10)
+
+typedef struct {
+ uint8_t byte_num; /*!< cmd byte number */
+ uint8_t ack_en; /*!< ack check enable */
+ uint8_t ack_exp; /*!< expected ack level to get */
+ uint8_t ack_val; /*!< ack value to send */
+ uint8_t* data; /*!< data address */
+ uint8_t byte_cmd; /*!< to save cmd for one byte command mode */
+ i2c_opmode_t op_code; /*!< haredware cmd type */
+}i2c_cmd_t;
+
+typedef struct i2c_cmd_link{
+ i2c_cmd_t cmd; /*!< command in current cmd link */
+ struct i2c_cmd_link *next; /*!< next cmd link */
+} i2c_cmd_link_t;
+
+typedef struct {
+ i2c_cmd_link_t* head; /*!< head of the command link */
+ i2c_cmd_link_t* cur; /*!< last node of the command link */
+ i2c_cmd_link_t* free; /*!< the first node to free of the command link */
+} i2c_cmd_desc_t;
+
+typedef enum {
+ I2C_STATUS_READ, /*!< read status for current master command */
+ I2C_STATUS_WRITE, /*!< write status for current master command */
+ I2C_STATUS_IDLE, /*!< idle status for current master command */
+ I2C_STATUS_ACK_ERROR, /*!< ack error status for current master command */
+ I2C_STATUS_DONE, /*!< I2C command done */
+ I2C_STATUS_TIMEOUT, /*!< I2C bus status error, and operation timeout */
+} i2c_status_t;
+
+typedef struct {
+ int type;
+} i2c_cmd_evt_t;
+
+typedef struct {
+ int i2c_num; /*!< I2C port number */
+ int mode; /*!< I2C mode, master or slave */
+ intr_handle_t intr_handle; /*!< I2C interrupt handle*/
+ int cmd_idx; /*!< record current command index, for master mode */
+ int status; /*!< record current command status, for master mode */
+ int rx_cnt; /*!< record current read index, for master mode */
+ uint8_t data_buf[I2C_FIFO_LEN]; /*!< a buffer to store i2c fifo data */
+
+ i2c_cmd_desc_t cmd_link; /*!< I2C command link */
+ QueueHandle_t cmd_evt_queue; /*!< I2C command event queue */
+#if CONFIG_SPIRAM_USE_MALLOC
+ uint8_t* evt_queue_storage; /*!< The buffer that will hold the items in the queue */
+ int intr_alloc_flags; /*!< Used to allocate the interrupt */
+ StaticQueue_t evt_queue_buffer; /*!< The buffer that will hold the queue structure*/
+#endif
+ xSemaphoreHandle cmd_mux; /*!< semaphore to lock command process */
+ size_t tx_fifo_remain; /*!< tx fifo remain length, for master mode */
+ size_t rx_fifo_remain; /*!< rx fifo remain length, for master mode */
+
+ xSemaphoreHandle slv_rx_mux; /*!< slave rx buffer mux */
+ xSemaphoreHandle slv_tx_mux; /*!< slave tx buffer mux */
+ size_t rx_buf_length; /*!< rx buffer length */
+ RingbufHandle_t rx_ring_buf; /*!< rx ringbuffer handler of slave mode */
+ size_t tx_buf_length; /*!< tx buffer length */
+ RingbufHandle_t tx_ring_buf; /*!< tx ringbuffer handler of slave mode */
+} i2c_obj_t;
+
+static i2c_obj_t *p_i2c_obj[I2C_NUM_MAX] = {0};
+static void i2c_isr_handler_default(void* arg);
+static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num);
+static esp_err_t IRAM_ATTR i2c_hw_fsm_reset(i2c_port_t i2c_num);
+
+/*
+ For i2c master mode, we don't need to use a buffer for the data, the APIs will execute the master commands
+and return after all of the commands have been sent out or when error occurs. So when we send master commands,
+we should free or modify the source data only after the i2c_master_cmd_begin function returns.
+ For i2c slave mode, we need a data buffer to stash the sending and receiving data, because the hardware fifo
+has only 32 bytes.
+*/
+esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_buf_len, size_t slv_tx_buf_len,
+ int intr_alloc_flags)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(mode == I2C_MODE_MASTER || ( slv_rx_buf_len > 100 || slv_tx_buf_len > 100 ), I2C_SLAVE_BUFFER_LEN_ERR_STR,
+ ESP_ERR_INVALID_ARG);
+ uint32_t intr_mask = 0;
+ if (p_i2c_obj[i2c_num] == NULL) {
+
+#if !CONFIG_SPIRAM_USE_MALLOC
+ p_i2c_obj[i2c_num] = (i2c_obj_t*) calloc(1, sizeof(i2c_obj_t));
+#else
+ if( !(intr_alloc_flags & ESP_INTR_FLAG_IRAM) ) {
+ p_i2c_obj[i2c_num] = (i2c_obj_t*) calloc(1, sizeof(i2c_obj_t));
+ } else {
+ p_i2c_obj[i2c_num] = (i2c_obj_t*) heap_caps_calloc(1, sizeof(i2c_obj_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+ }
+#endif
+ if (p_i2c_obj[i2c_num] == NULL) {
+ ESP_LOGE(I2C_TAG, I2C_DRIVER_MALLOC_ERR_STR);
+ return ESP_FAIL;
+ }
+ i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
+ p_i2c->i2c_num = i2c_num;
+ p_i2c->mode = mode;
+ p_i2c->cmd_idx = 0;
+ p_i2c->rx_cnt = 0;
+ p_i2c->status = I2C_STATUS_IDLE;
+
+#if CONFIG_SPIRAM_USE_MALLOC
+ p_i2c->intr_alloc_flags = intr_alloc_flags;
+#endif
+ p_i2c->rx_fifo_remain = I2C_FIFO_LEN;
+ p_i2c->tx_fifo_remain = I2C_FIFO_LEN;
+
+ if (mode == I2C_MODE_SLAVE) {
+ //we only use ringbuffer for slave mode.
+ if (slv_rx_buf_len > 0) {
+ p_i2c->rx_ring_buf = xRingbufferCreate(slv_rx_buf_len, RINGBUF_TYPE_BYTEBUF);
+ if (p_i2c->rx_ring_buf == NULL) {
+ ESP_LOGE(I2C_TAG, I2C_BUF_ERR_STR);
+ goto err;
+ }
+ p_i2c->rx_buf_length = slv_rx_buf_len;
+ } else {
+ p_i2c->rx_ring_buf = NULL;
+ p_i2c->rx_buf_length = 0;
+ }
+ if (slv_tx_buf_len > 0) {
+ p_i2c->tx_ring_buf = xRingbufferCreate(slv_tx_buf_len, RINGBUF_TYPE_BYTEBUF);
+ if (p_i2c->tx_ring_buf == NULL) {
+ ESP_LOGE(I2C_TAG, I2C_BUF_ERR_STR);
+ goto err;
+ }
+ p_i2c->tx_buf_length = slv_tx_buf_len;
+ } else {
+ p_i2c->tx_ring_buf = NULL;
+ p_i2c->tx_buf_length = 0;
+ }
+ p_i2c->slv_rx_mux = xSemaphoreCreateMutex();
+ p_i2c->slv_tx_mux = xSemaphoreCreateMutex();
+ if (p_i2c->slv_rx_mux == NULL || p_i2c->slv_tx_mux == NULL) {
+ ESP_LOGE(I2C_TAG, I2C_SEM_ERR_STR);
+ goto err;
+ }
+ intr_mask |= ( I2C_RXFIFO_FULL_INT_ENA_M | I2C_TRANS_COMPLETE_INT_ENA_M);
+ } else {
+ //semaphore to sync sending process, because we only have 32 bytes for hardware fifo.
+ p_i2c->cmd_mux = xSemaphoreCreateMutex();
+#if !CONFIG_SPIRAM_USE_MALLOC
+ p_i2c->cmd_evt_queue = xQueueCreate(I2C_EVT_QUEUE_LEN, sizeof(i2c_cmd_evt_t));
+#else
+ if( !(intr_alloc_flags & ESP_INTR_FLAG_IRAM) ) {
+ p_i2c->cmd_evt_queue = xQueueCreate(I2C_EVT_QUEUE_LEN, sizeof(i2c_cmd_evt_t));
+ } else {
+ p_i2c->evt_queue_storage = (uint8_t *)heap_caps_calloc(I2C_EVT_QUEUE_LEN, sizeof(i2c_cmd_evt_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+ if( p_i2c->evt_queue_storage == NULL ) {
+ ESP_LOGE(I2C_TAG, I2C_DRIVER_MALLOC_ERR_STR);
+ goto err;
+ }
+ memset(&p_i2c->evt_queue_buffer, 0, sizeof(StaticQueue_t));
+ p_i2c->cmd_evt_queue = xQueueCreateStatic(I2C_EVT_QUEUE_LEN, sizeof(i2c_cmd_evt_t), p_i2c->evt_queue_storage, &p_i2c->evt_queue_buffer);
+ }
+#endif
+ if (p_i2c->cmd_mux == NULL || p_i2c->cmd_evt_queue == NULL) {
+ ESP_LOGE(I2C_TAG, I2C_SEM_ERR_STR);
+ goto err;
+ }
+ //command link
+ p_i2c->cmd_link.cur = NULL;
+ p_i2c->cmd_link.head = NULL;
+ p_i2c->cmd_link.free = NULL;
+
+ p_i2c->tx_ring_buf = NULL;
+ p_i2c->rx_buf_length = 0;
+ p_i2c->tx_ring_buf = NULL;
+ p_i2c->tx_buf_length = 0;
+ intr_mask |= I2C_ARBITRATION_LOST_INT_ENA_M | I2C_TIME_OUT_INT_ST_M;
+ }
+ } else {
+ ESP_LOGE(I2C_TAG, I2C_DRIVER_ERR_STR);
+ return ESP_FAIL;
+ }
+ //hook isr handler
+ i2c_isr_register(i2c_num, i2c_isr_handler_default, p_i2c_obj[i2c_num], intr_alloc_flags, &p_i2c_obj[i2c_num]->intr_handle);
+ intr_mask |= ( I2C_TRANS_COMPLETE_INT_ENA_M |
+ I2C_TRANS_START_INT_ENA_M |
+ I2C_ACK_ERR_INT_ENA_M |
+ I2C_RXFIFO_OVF_INT_ENA_M |
+ I2C_SLAVE_TRAN_COMP_INT_ENA_M);
+ I2C[i2c_num]->int_clr.val = intr_mask;
+ I2C[i2c_num]->int_ena.val = intr_mask;
+ return ESP_OK;
+
+ err:
+ //Some error has happened. Free/destroy all allocated things and return ESP_FAIL.
+ if (p_i2c_obj[i2c_num]) {
+ if (p_i2c_obj[i2c_num]->rx_ring_buf) {
+ vRingbufferDelete(p_i2c_obj[i2c_num]->rx_ring_buf);
+ p_i2c_obj[i2c_num]->rx_ring_buf = NULL;
+ p_i2c_obj[i2c_num]->rx_buf_length = 0;
+ }
+ if (p_i2c_obj[i2c_num]->tx_ring_buf) {
+ vRingbufferDelete(p_i2c_obj[i2c_num]->tx_ring_buf);
+ p_i2c_obj[i2c_num]->tx_ring_buf = NULL;
+ p_i2c_obj[i2c_num]->tx_buf_length = 0;
+ }
+ if (p_i2c_obj[i2c_num]->cmd_evt_queue) {
+ vQueueDelete(p_i2c_obj[i2c_num]->cmd_evt_queue);
+ p_i2c_obj[i2c_num]->cmd_evt_queue = NULL;
+ }
+ if (p_i2c_obj[i2c_num]->cmd_mux) {
+ vSemaphoreDelete(p_i2c_obj[i2c_num]->cmd_mux);
+ }
+ if (p_i2c_obj[i2c_num]->slv_rx_mux) {
+ vSemaphoreDelete(p_i2c_obj[i2c_num]->slv_rx_mux);
+ }
+ if (p_i2c_obj[i2c_num]->slv_tx_mux) {
+ vSemaphoreDelete(p_i2c_obj[i2c_num]->slv_tx_mux);
+ }
+#if CONFIG_SPIRAM_USE_MALLOC
+ if (p_i2c_obj[i2c_num]->evt_queue_storage) {
+ free(p_i2c_obj[i2c_num]->evt_queue_storage);
+ p_i2c_obj[i2c_num]->evt_queue_storage = NULL;
+ }
+#endif
+ }
+ free(p_i2c_obj[i2c_num]);
+ p_i2c_obj[i2c_num] = NULL;
+ return ESP_FAIL;
+}
+
+static esp_err_t i2c_hw_enable(i2c_port_t i2c_num)
+{
+ if (i2c_num == I2C_NUM_0) {
+ periph_module_enable(PERIPH_I2C0_MODULE);
+ } else if (i2c_num == I2C_NUM_1) {
+ periph_module_enable(PERIPH_I2C1_MODULE);
+ }
+ return ESP_OK;
+}
+
+static esp_err_t i2c_hw_disable(i2c_port_t i2c_num)
+{
+ if (i2c_num == I2C_NUM_0) {
+ periph_module_disable(PERIPH_I2C0_MODULE);
+ } else if (i2c_num == I2C_NUM_1) {
+ periph_module_disable(PERIPH_I2C1_MODULE);
+ }
+ return ESP_OK;
+}
+
+esp_err_t i2c_driver_delete(i2c_port_t i2c_num)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(p_i2c_obj[i2c_num] != NULL, I2C_DRIVER_ERR_STR, ESP_FAIL);
+
+ i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
+
+ I2C[i2c_num]->int_ena.val = 0;
+ esp_intr_free(p_i2c->intr_handle);
+ p_i2c->intr_handle = NULL;
+
+ if (p_i2c->cmd_mux) {
+ xSemaphoreTake(p_i2c->cmd_mux, portMAX_DELAY);
+ vSemaphoreDelete(p_i2c->cmd_mux);
+ }
+ if (p_i2c_obj[i2c_num]->cmd_evt_queue) {
+ vQueueDelete(p_i2c_obj[i2c_num]->cmd_evt_queue);
+ p_i2c_obj[i2c_num]->cmd_evt_queue = NULL;
+ }
+ if (p_i2c->slv_rx_mux) {
+ vSemaphoreDelete(p_i2c->slv_rx_mux);
+ }
+ if (p_i2c->slv_tx_mux) {
+ vSemaphoreDelete(p_i2c->slv_tx_mux);
+ }
+
+ if (p_i2c->rx_ring_buf) {
+ vRingbufferDelete(p_i2c->rx_ring_buf);
+ p_i2c->rx_ring_buf = NULL;
+ p_i2c->rx_buf_length = 0;
+ }
+ if (p_i2c->tx_ring_buf) {
+ vRingbufferDelete(p_i2c->tx_ring_buf);
+ p_i2c->tx_ring_buf = NULL;
+ p_i2c->tx_buf_length = 0;
+ }
+#if CONFIG_SPIRAM_USE_MALLOC
+ if (p_i2c_obj[i2c_num]->evt_queue_storage) {
+ free(p_i2c_obj[i2c_num]->evt_queue_storage);
+ p_i2c_obj[i2c_num]->evt_queue_storage = NULL;
+ }
+#endif
+
+ free(p_i2c_obj[i2c_num]);
+ p_i2c_obj[i2c_num] = NULL;
+
+ i2c_hw_disable(i2c_num);
+ return ESP_OK;
+}
+
+esp_err_t i2c_reset_tx_fifo(i2c_port_t i2c_num)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ I2C[i2c_num]->fifo_conf.tx_fifo_rst = 1;
+ I2C[i2c_num]->fifo_conf.tx_fifo_rst = 0;
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+esp_err_t i2c_reset_rx_fifo(i2c_port_t i2c_num)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ I2C[i2c_num]->fifo_conf.rx_fifo_rst = 1;
+ I2C[i2c_num]->fifo_conf.rx_fifo_rst = 0;
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+static void IRAM_ATTR i2c_isr_handler_default(void* arg)
+{
+ i2c_obj_t* p_i2c = (i2c_obj_t*) arg;
+ int i2c_num = p_i2c->i2c_num;
+ uint32_t status = I2C[i2c_num]->int_status.val;
+ int idx = 0;
+
+ portBASE_TYPE HPTaskAwoken = pdFALSE;
+ while (status != 0) {
+ status = I2C[i2c_num]->int_status.val;
+ if (status & I2C_TX_SEND_EMPTY_INT_ST_M) {
+ I2C[i2c_num]->int_clr.tx_send_empty = 1;
+ } else if (status & I2C_RX_REC_FULL_INT_ST_M) {
+ I2C[i2c_num]->int_clr.rx_rec_full = 1;
+ } else if (status & I2C_ACK_ERR_INT_ST_M) {
+ I2C[i2c_num]->int_ena.ack_err = 0;
+ I2C[i2c_num]->int_clr.ack_err = 1;
+ if (p_i2c->mode == I2C_MODE_MASTER) {
+ p_i2c_obj[i2c_num]->status = I2C_STATUS_ACK_ERROR;
+ I2C[i2c_num]->int_clr.ack_err = 1;
+ //get error ack value from slave device, stop the commands
+ i2c_master_cmd_begin_static(i2c_num);
+ }
+ } else if (status & I2C_TRANS_START_INT_ST_M) {
+ I2C[i2c_num]->int_clr.trans_start = 1;
+ } else if (status & I2C_TIME_OUT_INT_ST_M) {
+ I2C[i2c_num]->int_ena.time_out = 0;
+ I2C[i2c_num]->int_clr.time_out = 1;
+ p_i2c_obj[i2c_num]->status = I2C_STATUS_TIMEOUT;
+ i2c_master_cmd_begin_static(i2c_num);
+ } else if (status & I2C_TRANS_COMPLETE_INT_ST_M) {
+ I2C[i2c_num]->int_clr.trans_complete = 1;
+ if (p_i2c->mode == I2C_MODE_SLAVE) {
+ int rx_fifo_cnt = I2C[i2c_num]->status_reg.rx_fifo_cnt;
+ for (idx = 0; idx < rx_fifo_cnt; idx++) {
+ p_i2c->data_buf[idx] = I2C[i2c_num]->fifo_data.data;
+ }
+ xRingbufferSendFromISR(p_i2c->rx_ring_buf, p_i2c->data_buf, rx_fifo_cnt, &HPTaskAwoken);
+ I2C[i2c_num]->int_clr.rx_fifo_full = 1;
+ } else {
+ // add check for unexcepted situations caused by noise.
+ if (p_i2c->status != I2C_STATUS_ACK_ERROR && p_i2c->status != I2C_STATUS_IDLE) {
+ i2c_master_cmd_begin_static(i2c_num);
+ }
+ }
+ } else if (status & I2C_MASTER_TRAN_COMP_INT_ST_M) {
+ I2C[i2c_num]->int_clr.master_tran_comp = 1;
+ } else if (status & I2C_ARBITRATION_LOST_INT_ST_M) {
+ I2C[i2c_num]->int_clr.arbitration_lost = 1;
+ p_i2c_obj[i2c_num]->status = I2C_STATUS_TIMEOUT;
+ i2c_master_cmd_begin_static(i2c_num);
+ } else if (status & I2C_SLAVE_TRAN_COMP_INT_ST_M) {
+ I2C[i2c_num]->int_clr.slave_tran_comp = 1;
+ } else if (status & I2C_END_DETECT_INT_ST_M) {
+ I2C[i2c_num]->int_ena.end_detect = 0;
+ I2C[i2c_num]->int_clr.end_detect = 1;
+ i2c_master_cmd_begin_static(i2c_num);
+ } else if (status & I2C_RXFIFO_OVF_INT_ST_M) {
+ I2C[i2c_num]->int_clr.rx_fifo_ovf = 1;
+ } else if (status & I2C_TXFIFO_EMPTY_INT_ST_M) {
+ int tx_fifo_rem = I2C_FIFO_LEN - I2C[i2c_num]->status_reg.tx_fifo_cnt;
+ size_t size = 0;
+ uint8_t *data = (uint8_t*) xRingbufferReceiveUpToFromISR(p_i2c->tx_ring_buf, &size, tx_fifo_rem);
+ if (data) {
+ for (idx = 0; idx < size; idx++) {
+ WRITE_PERI_REG(I2C_DATA_APB_REG(i2c_num), data[idx]);
+ }
+ vRingbufferReturnItemFromISR(p_i2c->tx_ring_buf, data, &HPTaskAwoken);
+ I2C[i2c_num]->int_ena.tx_fifo_empty = 1;
+ I2C[i2c_num]->int_clr.tx_fifo_empty = 1;
+ } else {
+ I2C[i2c_num]->int_ena.tx_fifo_empty = 0;
+ I2C[i2c_num]->int_clr.tx_fifo_empty = 1;
+ }
+ } else if (status & I2C_RXFIFO_FULL_INT_ST_M) {
+ int rx_fifo_cnt = I2C[i2c_num]->status_reg.rx_fifo_cnt;
+ for (idx = 0; idx < rx_fifo_cnt; idx++) {
+ p_i2c->data_buf[idx] = I2C[i2c_num]->fifo_data.data;
+ }
+ xRingbufferSendFromISR(p_i2c->rx_ring_buf, p_i2c->data_buf, rx_fifo_cnt, &HPTaskAwoken);
+ I2C[i2c_num]->int_clr.rx_fifo_full = 1;
+ } else {
+ I2C[i2c_num]->int_clr.val = status;
+ }
+ }
+ if (p_i2c->mode == I2C_MODE_MASTER) {
+ i2c_cmd_evt_t evt;
+ evt.type = I2C_CMD_EVT_ALIVE;
+ xQueueSendFromISR(p_i2c->cmd_evt_queue, &evt, &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_set_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t tx_trans_mode, i2c_trans_mode_t rx_trans_mode)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(tx_trans_mode < I2C_DATA_MODE_MAX, I2C_TRANS_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(rx_trans_mode < I2C_DATA_MODE_MAX, I2C_TRANS_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ I2C[i2c_num]->ctr.rx_lsb_first = rx_trans_mode; //set rx data msb first
+ I2C[i2c_num]->ctr.tx_lsb_first = tx_trans_mode; //set tx data msb first
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+esp_err_t i2c_get_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t *tx_trans_mode, i2c_trans_mode_t *rx_trans_mode)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ if (tx_trans_mode) {
+ *tx_trans_mode = I2C[i2c_num]->ctr.tx_lsb_first;
+ }
+ if (rx_trans_mode) {
+ *rx_trans_mode = I2C[i2c_num]->ctr.rx_lsb_first;
+ }
+ return ESP_OK;
+}
+
+/* Some slave device will die by accident and keep the SDA in low level,
+ * in this case, master should send several clock to make the slave release the bus.
+ * Slave mode of ESP32 might also get in wrong state that held the SDA low,
+ * in this case, master device could send a stop signal to make esp32 slave release the bus.
+ **/
+static esp_err_t i2c_master_clear_bus(i2c_port_t i2c_num)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ int sda_in_sig = 0, scl_in_sig = 0;
+ if (i2c_num == I2C_NUM_0) {
+ sda_in_sig = I2CEXT0_SDA_IN_IDX;
+ scl_in_sig = I2CEXT0_SCL_IN_IDX;
+ } else if (i2c_num == I2C_NUM_1) {
+ sda_in_sig = I2CEXT1_SDA_IN_IDX;
+ scl_in_sig = I2CEXT1_SCL_IN_IDX;
+ }
+ int scl_io = GPIO.func_in_sel_cfg[scl_in_sig].func_sel;
+ int sda_io = GPIO.func_in_sel_cfg[sda_in_sig].func_sel;
+ I2C_CHECK((GPIO_IS_VALID_OUTPUT_GPIO(scl_io)), I2C_SCL_IO_ERR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK((GPIO_IS_VALID_GPIO(sda_io)), I2C_SDA_IO_ERR_STR, ESP_ERR_INVALID_ARG);
+ // We do not check whether the SDA line is low
+ // because after some serious interference, the bus may keep high all the time and the i2c bus is out of service.
+ gpio_set_direction(scl_io, GPIO_MODE_OUTPUT_OD);
+ gpio_set_direction(sda_io, GPIO_MODE_OUTPUT_OD);
+ gpio_set_level(scl_io, 1);
+ gpio_set_level(sda_io, 1);
+ gpio_set_level(sda_io, 0);
+ for (int i = 0; i < 9; i++) {
+ gpio_set_level(scl_io, 0);
+ gpio_set_level(scl_io, 1);
+ }
+ gpio_set_level(sda_io, 1);
+ i2c_set_pin(i2c_num, sda_io, scl_io, 1, 1, I2C_MODE_MASTER);
+ return ESP_OK;
+}
+
+/**if the power and SDA/SCL wires are in proper condition, everything works find with reading the slave.
+ * If we remove the power supply for the slave during I2C is reading, or directly connect SDA or SCL to ground,
+ * this would cause the I2C FSM get stuck in wrong state, all we can do is to reset the I2C hardware in this case.
+ **/
+static esp_err_t i2c_hw_fsm_reset(i2c_port_t i2c_num)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ uint32_t ctr = I2C[i2c_num]->ctr.val;
+ uint32_t fifo_conf = I2C[i2c_num]->fifo_conf.val;
+ uint32_t scl_low_period = I2C[i2c_num]->scl_low_period.val;
+ uint32_t scl_high_period = I2C[i2c_num]->scl_high_period.val;
+ uint32_t scl_start_hold = I2C[i2c_num]->scl_start_hold.val;
+ uint32_t scl_rstart_setup = I2C[i2c_num]->scl_rstart_setup.val;
+ uint32_t scl_stop_hold = I2C[i2c_num]->scl_stop_hold.val;
+ uint32_t scl_stop_setup = I2C[i2c_num]->scl_stop_setup.val;
+ uint32_t sda_hold = I2C[i2c_num]->sda_hold.val;
+ uint32_t sda_sample = I2C[i2c_num]->sda_sample.val;
+ uint32_t timeout = I2C[i2c_num]->timeout.val;
+ uint32_t scl_filter_cfg = I2C[i2c_num]->scl_filter_cfg.val;
+ uint32_t sda_filter_cfg = I2C[i2c_num]->sda_filter_cfg.val;
+ uint32_t slave_addr = I2C[i2c_num]->slave_addr.val;
+
+ //to reset the I2C hw module, we need re-enable the hw
+ i2c_hw_disable(i2c_num);
+ i2c_master_clear_bus(i2c_num);
+ i2c_hw_enable(i2c_num);
+ I2C[i2c_num]->int_ena.val = 0;
+ I2C[i2c_num]->ctr.val = ctr & (~I2C_TRANS_START_M);
+ I2C[i2c_num]->fifo_conf.val = fifo_conf;
+ I2C[i2c_num]->scl_low_period.val = scl_low_period;
+ I2C[i2c_num]->scl_high_period.val = scl_high_period;
+ I2C[i2c_num]->scl_start_hold.val = scl_start_hold;
+ I2C[i2c_num]->scl_rstart_setup.val = scl_rstart_setup;
+ I2C[i2c_num]->scl_stop_hold.val = scl_stop_hold;
+ I2C[i2c_num]->scl_stop_setup.val = scl_stop_setup;
+ I2C[i2c_num]->sda_hold.val = sda_hold;
+ I2C[i2c_num]->sda_sample.val = sda_sample;
+ I2C[i2c_num]->timeout.val = timeout;
+ I2C[i2c_num]->scl_filter_cfg.val = scl_filter_cfg;
+ I2C[i2c_num]->sda_filter_cfg.val = sda_filter_cfg;
+ uint32_t intr_mask = ( I2C_TRANS_COMPLETE_INT_ENA_M
+ | I2C_TRANS_START_INT_ENA_M
+ | I2C_ACK_ERR_INT_ENA_M
+ | I2C_RXFIFO_OVF_INT_ENA_M
+ | I2C_SLAVE_TRAN_COMP_INT_ENA_M
+ | I2C_TIME_OUT_INT_ENA_M);
+ if (I2C[i2c_num]->ctr.ms_mode == I2C_MODE_SLAVE) {
+ I2C[i2c_num]->slave_addr.val = slave_addr;
+ intr_mask |= ( I2C_RXFIFO_FULL_INT_ENA_M | I2C_TRANS_COMPLETE_INT_ENA_M);
+ } else {
+ intr_mask |= I2C_ARBITRATION_LOST_INT_ENA_M;
+ }
+ I2C[i2c_num]->int_clr.val = intr_mask;
+ I2C[i2c_num]->int_ena.val = intr_mask;
+ return ESP_OK;
+}
+
+esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t* i2c_conf)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(i2c_conf != NULL, I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(i2c_conf->mode < I2C_MODE_MAX, I2C_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
+
+ esp_err_t ret = i2c_set_pin(i2c_num, i2c_conf->sda_io_num, i2c_conf->scl_io_num,
+ i2c_conf->sda_pullup_en, i2c_conf->scl_pullup_en, i2c_conf->mode);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ // Reset the I2C hardware in case there is a soft reboot.
+ i2c_hw_disable(i2c_num);
+ i2c_hw_enable(i2c_num);
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ I2C[i2c_num]->ctr.rx_lsb_first = I2C_DATA_MODE_MSB_FIRST; //set rx data msb first
+ I2C[i2c_num]->ctr.tx_lsb_first = I2C_DATA_MODE_MSB_FIRST; //set tx data msb first
+ I2C[i2c_num]->ctr.ms_mode = i2c_conf->mode; //mode for master or slave
+ I2C[i2c_num]->ctr.sda_force_out = 1; // set open-drain output mode
+ I2C[i2c_num]->ctr.scl_force_out = 1; // set open-drain output mode
+ I2C[i2c_num]->ctr.sample_scl_level = 0; //sample at high level of clock
+
+ if (i2c_conf->mode == I2C_MODE_SLAVE) { //slave mode
+ I2C[i2c_num]->slave_addr.addr = i2c_conf->slave.slave_addr;
+ I2C[i2c_num]->slave_addr.en_10bit = i2c_conf->slave.addr_10bit_en;
+ I2C[i2c_num]->fifo_conf.nonfifo_en = 0;
+ I2C[i2c_num]->fifo_conf.fifo_addr_cfg_en = 0;
+ I2C[i2c_num]->fifo_conf.rx_fifo_full_thrhd = I2C_FIFO_FULL_THRESH_VAL;
+ I2C[i2c_num]->fifo_conf.tx_fifo_empty_thrhd = I2C_FIFO_EMPTY_THRESH_VAL;
+ I2C[i2c_num]->ctr.trans_start = 0;
+ I2C[i2c_num]->timeout.tout = I2C_SLAVE_TIMEOUT_DEFAULT;
+ //set timing for data
+ I2C[i2c_num]->sda_hold.time = I2C_SLAVE_SDA_HOLD_DEFAULT;
+ I2C[i2c_num]->sda_sample.time = I2C_SLAVE_SDA_SAMPLE_DEFAULT;
+ } else {
+ I2C[i2c_num]->fifo_conf.nonfifo_en = 0;
+ int cycle = (I2C_APB_CLK_FREQ / i2c_conf->master.clk_speed);
+ int half_cycle = cycle / 2;
+ I2C[i2c_num]->timeout.tout = cycle * I2C_MASTER_TOUT_CNUM_DEFAULT;
+ //set timing for data
+ I2C[i2c_num]->sda_hold.time = half_cycle / 2;
+ I2C[i2c_num]->sda_sample.time = half_cycle / 2;
+
+ I2C[i2c_num]->scl_low_period.period = half_cycle;
+ I2C[i2c_num]->scl_high_period.period = half_cycle;
+ //set timing for start signal
+ I2C[i2c_num]->scl_start_hold.time = half_cycle;
+ I2C[i2c_num]->scl_rstart_setup.time = half_cycle;
+ //set timing for stop signal
+ I2C[i2c_num]->scl_stop_hold.time = half_cycle;
+ I2C[i2c_num]->scl_stop_setup.time = half_cycle;
+ }
+
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+esp_err_t i2c_set_period(i2c_port_t i2c_num, int high_period, int low_period)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK((high_period <= I2C_SCL_HIGH_PERIOD_V) && (high_period > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK((low_period <= I2C_SCL_LOW_PERIOD_V) && (low_period > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
+
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ I2C[i2c_num]->scl_high_period.period = high_period;
+ I2C[i2c_num]->scl_low_period.period = low_period;
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+esp_err_t i2c_get_period(i2c_port_t i2c_num, int* high_period, int* low_period)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ if (high_period) {
+ *high_period = I2C[i2c_num]->scl_high_period.period;
+ }
+ if (low_period) {
+ *low_period = I2C[i2c_num]->scl_low_period.period;
+ }
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+esp_err_t i2c_set_start_timing(i2c_port_t i2c_num, int setup_time, int hold_time)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK((hold_time <= I2C_SCL_START_HOLD_TIME_V) && (hold_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK((setup_time <= I2C_SCL_RSTART_SETUP_TIME_V) && (setup_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
+
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ I2C[i2c_num]->scl_start_hold.time = hold_time;
+ I2C[i2c_num]->scl_rstart_setup.time = setup_time;
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+esp_err_t i2c_get_start_timing(i2c_port_t i2c_num, int* setup_time, int* hold_time)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ if (hold_time) {
+ *hold_time = I2C[i2c_num]->scl_start_hold.time;
+ }
+ if (setup_time) {
+ *setup_time = I2C[i2c_num]->scl_rstart_setup.time;
+ }
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+esp_err_t i2c_set_stop_timing(i2c_port_t i2c_num, int setup_time, int hold_time)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK((setup_time <= I2C_SCL_STOP_SETUP_TIME_V) && (setup_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK((hold_time <= I2C_SCL_STOP_HOLD_TIME_V) && (hold_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
+
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ I2C[i2c_num]->scl_stop_hold.time = hold_time;
+ I2C[i2c_num]->scl_stop_setup.time = setup_time;
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+esp_err_t i2c_get_stop_timing(i2c_port_t i2c_num, int* setup_time, int* hold_time)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ if (setup_time) {
+ *setup_time = I2C[i2c_num]->scl_stop_setup.time;
+ }
+ if (hold_time) {
+ *hold_time = I2C[i2c_num]->scl_stop_hold.time;
+ }
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+esp_err_t i2c_set_data_timing(i2c_port_t i2c_num, int sample_time, int hold_time)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK((sample_time <= I2C_SDA_SAMPLE_TIME_V) && (sample_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK((hold_time <= I2C_SDA_HOLD_TIME_V) && (hold_time > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
+
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ I2C[i2c_num]->sda_hold.time = hold_time;
+ I2C[i2c_num]->sda_sample.time = sample_time;
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+esp_err_t i2c_get_data_timing(i2c_port_t i2c_num, int* sample_time, int* hold_time)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ if (sample_time) {
+ *sample_time = I2C[i2c_num]->sda_sample.time;
+ }
+ if (hold_time) {
+ *hold_time = I2C[i2c_num]->sda_hold.time;
+ }
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+esp_err_t i2c_set_timeout(i2c_port_t i2c_num, int timeout)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK((timeout <= I2C_TIME_OUT_REG_V) && (timeout > 0), I2C_TIMEING_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
+
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ I2C[i2c_num]->timeout.tout = timeout;
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ return ESP_OK;
+}
+
+esp_err_t i2c_get_timeout(i2c_port_t i2c_num, int* timeout)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ if (timeout) {
+ *timeout = I2C[i2c_num]->timeout.tout;
+ }
+ return ESP_OK;
+}
+
+esp_err_t i2c_isr_register(i2c_port_t i2c_num, void (*fn)(void*), void * arg, int intr_alloc_flags, intr_handle_t *handle)
+{
+ I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(fn != NULL, I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
+ esp_err_t ret;
+ switch (i2c_num) {
+ case I2C_NUM_1:
+ ret = esp_intr_alloc(ETS_I2C_EXT1_INTR_SOURCE, intr_alloc_flags, fn, arg, handle);
+ break;
+ case I2C_NUM_0:
+ default:
+ ret = esp_intr_alloc(ETS_I2C_EXT0_INTR_SOURCE, intr_alloc_flags, fn, arg, handle);
+ break;
+ }
+ return ret;
+}
+
+esp_err_t i2c_isr_free(intr_handle_t handle)
+{
+ return esp_intr_free(handle);
+}
+
+esp_err_t i2c_set_pin(i2c_port_t i2c_num, int sda_io_num, int scl_io_num, gpio_pullup_t sda_pullup_en, gpio_pullup_t scl_pullup_en, i2c_mode_t mode)
+{
+ I2C_CHECK(( i2c_num < I2C_NUM_MAX ), I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(((sda_io_num < 0) || ((GPIO_IS_VALID_OUTPUT_GPIO(sda_io_num)))), I2C_SDA_IO_ERR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(scl_io_num < 0 ||
+ (GPIO_IS_VALID_OUTPUT_GPIO(scl_io_num)) ||
+ (GPIO_IS_VALID_GPIO(scl_io_num) && mode == I2C_MODE_SLAVE),
+ I2C_SCL_IO_ERR_STR,
+ ESP_ERR_INVALID_ARG);
+ I2C_CHECK(sda_io_num < 0 ||
+ (sda_pullup_en == GPIO_PULLUP_ENABLE && GPIO_IS_VALID_OUTPUT_GPIO(sda_io_num)) ||
+ sda_pullup_en == GPIO_PULLUP_DISABLE, I2C_GPIO_PULLUP_ERR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(scl_io_num < 0 ||
+ (scl_pullup_en == GPIO_PULLUP_ENABLE && GPIO_IS_VALID_OUTPUT_GPIO(scl_io_num)) ||
+ scl_pullup_en == GPIO_PULLUP_DISABLE, I2C_GPIO_PULLUP_ERR_STR, ESP_ERR_INVALID_ARG);
+
+ int sda_in_sig, sda_out_sig, scl_in_sig, scl_out_sig;
+ switch (i2c_num) {
+ case I2C_NUM_1:
+ sda_out_sig = I2CEXT1_SDA_OUT_IDX;
+ sda_in_sig = I2CEXT1_SDA_IN_IDX;
+ scl_out_sig = I2CEXT1_SCL_OUT_IDX;
+ scl_in_sig = I2CEXT1_SCL_IN_IDX;
+ break;
+ case I2C_NUM_0:
+ default:
+ sda_out_sig = I2CEXT0_SDA_OUT_IDX;
+ sda_in_sig = I2CEXT0_SDA_IN_IDX;
+ scl_out_sig = I2CEXT0_SCL_OUT_IDX;
+ scl_in_sig = I2CEXT0_SCL_IN_IDX;
+ break;
+ }
+ if (sda_io_num >= 0) {
+ gpio_set_level(sda_io_num, I2C_IO_INIT_LEVEL);
+ PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[sda_io_num], PIN_FUNC_GPIO);
+ gpio_set_direction(sda_io_num, GPIO_MODE_INPUT_OUTPUT_OD);
+
+ if (sda_pullup_en == GPIO_PULLUP_ENABLE) {
+ gpio_set_pull_mode(sda_io_num, GPIO_PULLUP_ONLY);
+ } else {
+ gpio_set_pull_mode(sda_io_num, GPIO_FLOATING);
+ }
+ gpio_matrix_out(sda_io_num, sda_out_sig, 0, 0);
+ gpio_matrix_in(sda_io_num, sda_in_sig, 0);
+ }
+
+ if (scl_io_num >= 0) {
+ gpio_set_level(scl_io_num, I2C_IO_INIT_LEVEL);
+ PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[scl_io_num], PIN_FUNC_GPIO);
+ if (mode == I2C_MODE_MASTER) {
+ gpio_set_direction(scl_io_num, GPIO_MODE_INPUT_OUTPUT_OD);
+ gpio_matrix_out(scl_io_num, scl_out_sig, 0, 0);
+ } else {
+ gpio_set_direction(scl_io_num, GPIO_MODE_INPUT);
+ }
+ if (scl_pullup_en == GPIO_PULLUP_ENABLE) {
+ gpio_set_pull_mode(scl_io_num, GPIO_PULLUP_ONLY);
+ } else {
+ gpio_set_pull_mode(scl_io_num, GPIO_FLOATING);
+ }
+ gpio_matrix_in(scl_io_num, scl_in_sig, 0);
+ }
+ return ESP_OK;
+}
+
+i2c_cmd_handle_t i2c_cmd_link_create()
+{
+#if !CONFIG_SPIRAM_USE_MALLOC
+ i2c_cmd_desc_t* cmd_desc = (i2c_cmd_desc_t*) calloc(1, sizeof(i2c_cmd_desc_t));
+#else
+ i2c_cmd_desc_t* cmd_desc = (i2c_cmd_desc_t*) heap_caps_calloc(1, sizeof(i2c_cmd_desc_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+#endif
+ return (i2c_cmd_handle_t) cmd_desc;
+}
+
+void i2c_cmd_link_delete(i2c_cmd_handle_t cmd_handle)
+{
+ if (cmd_handle == NULL) {
+ return;
+ }
+ i2c_cmd_desc_t* cmd = (i2c_cmd_desc_t*) cmd_handle;
+ while (cmd->free) {
+ i2c_cmd_link_t* ptmp = cmd->free;
+ cmd->free = cmd->free->next;
+ free(ptmp);
+ }
+ cmd->cur = NULL;
+ cmd->free = NULL;
+ cmd->head = NULL;
+ free(cmd_handle);
+ return;
+}
+
+static esp_err_t i2c_cmd_link_append(i2c_cmd_handle_t cmd_handle, i2c_cmd_t* cmd)
+{
+ i2c_cmd_desc_t* cmd_desc = (i2c_cmd_desc_t*) cmd_handle;
+ if (cmd_desc->head == NULL) {
+#if !CONFIG_SPIRAM_USE_MALLOC
+ cmd_desc->head = (i2c_cmd_link_t*) calloc(1, sizeof(i2c_cmd_link_t));
+#else
+ cmd_desc->head = (i2c_cmd_link_t*) heap_caps_calloc(1, sizeof(i2c_cmd_link_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+#endif
+ if (cmd_desc->head == NULL) {
+ ESP_LOGE(I2C_TAG, I2C_CMD_MALLOC_ERR_STR);
+ goto err;
+ }
+ cmd_desc->cur = cmd_desc->head;
+ cmd_desc->free = cmd_desc->head;
+ } else {
+#if !CONFIG_SPIRAM_USE_MALLOC
+ cmd_desc->cur->next = (i2c_cmd_link_t*) calloc(1, sizeof(i2c_cmd_link_t));
+#else
+ cmd_desc->cur->next = (i2c_cmd_link_t*) heap_caps_calloc(1, sizeof(i2c_cmd_link_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+#endif
+ if (cmd_desc->cur->next == NULL) {
+ ESP_LOGE(I2C_TAG, I2C_CMD_MALLOC_ERR_STR);
+ goto err;
+ }
+ cmd_desc->cur = cmd_desc->cur->next;
+ }
+ memcpy((uint8_t*) &cmd_desc->cur->cmd, (uint8_t*) cmd, sizeof(i2c_cmd_t));
+ cmd_desc->cur->next = NULL;
+ return ESP_OK;
+
+ err:
+ return ESP_FAIL;
+}
+
+esp_err_t i2c_master_start(i2c_cmd_handle_t cmd_handle)
+{
+ I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
+ i2c_cmd_t cmd;
+ cmd.ack_en = 0;
+ cmd.ack_exp = 0;
+ cmd.ack_val = 0;
+ cmd.byte_num = 0;
+ cmd.data = NULL;
+ cmd.op_code = I2C_CMD_RESTART;
+ return i2c_cmd_link_append(cmd_handle, &cmd);
+}
+
+esp_err_t i2c_master_stop(i2c_cmd_handle_t cmd_handle)
+{
+ I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
+ i2c_cmd_t cmd;
+ cmd.ack_en = 0;
+ cmd.ack_exp = 0;
+ cmd.ack_val = 0;
+ cmd.byte_num = 0;
+ cmd.data = NULL;
+ cmd.op_code = I2C_CMD_STOP;
+ return i2c_cmd_link_append(cmd_handle, &cmd);
+}
+
+esp_err_t i2c_master_write(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t data_len, bool ack_en)
+{
+ I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
+
+ uint8_t len_tmp;
+ int data_offset = 0;
+ esp_err_t ret;
+ while (data_len > 0) {
+ len_tmp = data_len > 0xff ? 0xff : data_len;
+ data_len -= len_tmp;
+ i2c_cmd_t cmd;
+ cmd.ack_en = ack_en;
+ cmd.ack_exp = 0;
+ cmd.ack_val = 0;
+ cmd.byte_num = len_tmp;
+ cmd.op_code = I2C_CMD_WRITE;
+ cmd.data = data + data_offset;
+ ret = i2c_cmd_link_append(cmd_handle, &cmd);
+ data_offset += len_tmp;
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ }
+ return ESP_OK;
+}
+
+esp_err_t i2c_master_write_byte(i2c_cmd_handle_t cmd_handle, uint8_t data, bool ack_en)
+{
+ I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
+ i2c_cmd_t cmd;
+ cmd.ack_en = ack_en;
+ cmd.ack_exp = 0;
+ cmd.ack_val = 0;
+ cmd.byte_num = 1;
+ cmd.op_code = I2C_CMD_WRITE;
+ cmd.data = NULL;
+ cmd.byte_cmd = data;
+ return i2c_cmd_link_append(cmd_handle, &cmd);
+}
+
+static esp_err_t i2c_master_read_static(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t data_len, i2c_ack_type_t ack)
+{
+ int len_tmp;
+ int data_offset = 0;
+ esp_err_t ret;
+ while (data_len > 0) {
+ len_tmp = data_len > 0xff ? 0xff : data_len;
+ data_len -= len_tmp;
+ i2c_cmd_t cmd;
+ cmd.ack_en = 0;
+ cmd.ack_exp = 0;
+ cmd.ack_val = ack & 0x1;
+ cmd.byte_num = len_tmp;
+ cmd.op_code = I2C_CMD_READ;
+ cmd.data = data + data_offset;
+ ret = i2c_cmd_link_append(cmd_handle, &cmd);
+ data_offset += len_tmp;
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ }
+ return ESP_OK;
+}
+
+esp_err_t i2c_master_read_byte(i2c_cmd_handle_t cmd_handle, uint8_t* data, i2c_ack_type_t ack)
+{
+ I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(ack < I2C_MASTER_ACK_MAX, I2C_ACK_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
+
+ i2c_cmd_t cmd;
+ cmd.ack_en = 0;
+ cmd.ack_exp = 0;
+ cmd.ack_val = ((ack == I2C_MASTER_LAST_NACK) ? I2C_MASTER_NACK : (ack & 0x1));
+ cmd.byte_num = 1;
+ cmd.op_code = I2C_CMD_READ;
+ cmd.data = data;
+ return i2c_cmd_link_append(cmd_handle, &cmd);
+}
+
+esp_err_t i2c_master_read(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t data_len, i2c_ack_type_t ack)
+{
+ I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(ack < I2C_MASTER_ACK_MAX, I2C_ACK_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(data_len > 0, I2C_DATA_LEN_ERR_STR, ESP_ERR_INVALID_ARG);
+
+ if(ack != I2C_MASTER_LAST_NACK) {
+ return i2c_master_read_static(cmd_handle, data, data_len, ack);
+ } else {
+ if(data_len == 1) {
+ return i2c_master_read_byte(cmd_handle, data, I2C_MASTER_NACK);
+ } else {
+ esp_err_t ret;
+ if((ret = i2c_master_read_static(cmd_handle, data, data_len - 1, I2C_MASTER_ACK)) != ESP_OK) {
+ return ret;
+ }
+ return i2c_master_read_byte(cmd_handle, data + data_len - 1, I2C_MASTER_NACK);
+ }
+ }
+}
+
+static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num)
+{
+ i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
+ portBASE_TYPE HPTaskAwoken = pdFALSE;
+ i2c_cmd_evt_t evt;
+ //This should never happen
+ if (p_i2c->mode == I2C_MODE_SLAVE) {
+ return;
+ }
+ if (p_i2c->status == I2C_STATUS_DONE) {
+ return;
+ } else if ((p_i2c->status == I2C_STATUS_ACK_ERROR)
+ || (p_i2c->status == I2C_STATUS_TIMEOUT)) {
+ I2C[i2c_num]->int_ena.end_detect = 0;
+ I2C[i2c_num]->int_clr.end_detect = 1;
+ if(p_i2c->status == I2C_STATUS_TIMEOUT) {
+ I2C[i2c_num]->int_clr.time_out = 1;
+ I2C[i2c_num]->int_ena.val = 0;
+ }
+ evt.type = I2C_CMD_EVT_DONE;
+ xQueueOverwriteFromISR(p_i2c->cmd_evt_queue, &evt, &HPTaskAwoken);
+ if (HPTaskAwoken == pdTRUE) {
+ portYIELD_FROM_ISR();
+ }
+ return;
+ } else if (p_i2c->cmd_link.head != NULL && p_i2c->status == I2C_STATUS_READ) {
+ i2c_cmd_t *cmd = &p_i2c->cmd_link.head->cmd;
+ while (p_i2c->rx_cnt-- > 0) {
+ *cmd->data++ = READ_PERI_REG(I2C_DATA_APB_REG(i2c_num));
+ }
+ if (cmd->byte_num > 0) {
+ p_i2c->rx_fifo_remain = I2C_FIFO_LEN;
+ p_i2c->cmd_idx = 0;
+ } else {
+ p_i2c->cmd_link.head = p_i2c->cmd_link.head->next;
+ }
+ }
+ if (p_i2c->cmd_link.head == NULL) {
+ p_i2c->cmd_link.cur = NULL;
+ evt.type = I2C_CMD_EVT_DONE;
+ xQueueOverwriteFromISR(p_i2c->cmd_evt_queue, &evt, &HPTaskAwoken);
+ if (HPTaskAwoken == pdTRUE) {
+ portYIELD_FROM_ISR();
+ }
+ // Return to the IDLE status after cmd_eve_done signal were send out.
+ p_i2c->status = I2C_STATUS_IDLE;
+ return;
+ }
+ while (p_i2c->cmd_link.head) {
+ i2c_cmd_t *cmd = &p_i2c->cmd_link.head->cmd;
+ I2C[i2c_num]->command[p_i2c->cmd_idx].val = 0;
+ I2C[i2c_num]->command[p_i2c->cmd_idx].ack_en = cmd->ack_en;
+ I2C[i2c_num]->command[p_i2c->cmd_idx].ack_exp = cmd->ack_exp;
+ I2C[i2c_num]->command[p_i2c->cmd_idx].ack_val = cmd->ack_val;
+ I2C[i2c_num]->command[p_i2c->cmd_idx].byte_num = cmd->byte_num;
+ I2C[i2c_num]->command[p_i2c->cmd_idx].op_code = cmd->op_code;
+ if (cmd->op_code == I2C_CMD_WRITE) {
+ uint32_t wr_filled = 0;
+ //TODO: to reduce interrupt number
+ if (cmd->data) {
+ while (p_i2c->tx_fifo_remain > 0 && cmd->byte_num > 0) {
+ WRITE_PERI_REG(I2C_DATA_APB_REG(i2c_num), *cmd->data++);
+ p_i2c->tx_fifo_remain--;
+ cmd->byte_num--;
+ wr_filled++;
+ }
+ } else {
+ WRITE_PERI_REG(I2C_DATA_APB_REG(i2c_num), cmd->byte_cmd);
+ p_i2c->tx_fifo_remain--;
+ cmd->byte_num--;
+ wr_filled ++;
+ }
+ //Workaround for register field operation.
+ I2C[i2c_num]->command[p_i2c->cmd_idx].byte_num = wr_filled;
+ I2C[i2c_num]->command[p_i2c->cmd_idx + 1].val = 0;
+ I2C[i2c_num]->command[p_i2c->cmd_idx + 1].op_code = I2C_CMD_END;
+ p_i2c->tx_fifo_remain = I2C_FIFO_LEN;
+ p_i2c->cmd_idx = 0;
+ if (cmd->byte_num > 0) {
+ } else {
+ p_i2c->cmd_link.head = p_i2c->cmd_link.head->next;
+ }
+ p_i2c->status = I2C_STATUS_WRITE;
+ break;
+ } else if(cmd->op_code == I2C_CMD_READ) {
+ //TODO: to reduce interrupt number
+ p_i2c->rx_cnt = cmd->byte_num > p_i2c->rx_fifo_remain ? p_i2c->rx_fifo_remain : cmd->byte_num;
+ cmd->byte_num -= p_i2c->rx_cnt;
+ I2C[i2c_num]->command[p_i2c->cmd_idx].byte_num = p_i2c->rx_cnt;
+ I2C[i2c_num]->command[p_i2c->cmd_idx].ack_val = cmd->ack_val;
+ I2C[i2c_num]->command[p_i2c->cmd_idx + 1].val = 0;
+ I2C[i2c_num]->command[p_i2c->cmd_idx + 1].op_code = I2C_CMD_END;
+ p_i2c->status = I2C_STATUS_READ;
+ break;
+ } else {
+ }
+ p_i2c->cmd_idx++;
+ p_i2c->cmd_link.head = p_i2c->cmd_link.head->next;
+ if (p_i2c->cmd_link.head == NULL || p_i2c->cmd_idx >= 15) {
+ p_i2c->tx_fifo_remain = I2C_FIFO_LEN;
+ p_i2c->cmd_idx = 0;
+ break;
+ }
+ }
+ I2C[i2c_num]->int_clr.end_detect = 1;
+ I2C[i2c_num]->int_ena.end_detect = 1;
+ I2C[i2c_num]->ctr.trans_start = 0;
+ I2C[i2c_num]->ctr.trans_start = 1;
+ return;
+}
+
+#if CONFIG_SPIRAM_USE_MALLOC
+//Check whether read or write buffer in cmd_link is internal.
+static bool is_cmd_link_buffer_internal(i2c_cmd_link_t *link)
+{
+ i2c_cmd_link_t* cmd_link = link;
+ while(cmd_link != NULL) {
+ if (cmd_link->cmd.op_code == I2C_CMD_WRITE || cmd_link->cmd.op_code == I2C_CMD_READ) {
+ if( cmd_link->cmd.data != NULL && !esp_ptr_internal(cmd_link->cmd.data)) {
+ return false;
+ }
+ }
+ cmd_link = cmd_link->next;
+ }
+ return true;
+}
+#endif
+
+esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle, TickType_t ticks_to_wait)
+{
+ I2C_CHECK(( i2c_num < I2C_NUM_MAX ), I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
+ I2C_CHECK(p_i2c_obj[i2c_num] != NULL, I2C_DRIVER_NOT_INSTALL_ERR_STR, ESP_ERR_INVALID_STATE);
+ I2C_CHECK(p_i2c_obj[i2c_num]->mode == I2C_MODE_MASTER, I2C_MASTER_MODE_ERR_STR, ESP_ERR_INVALID_STATE);
+ I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);
+
+#if CONFIG_SPIRAM_USE_MALLOC
+ //If the i2c read or write buffer is not in internal RAM, we will return ESP_FAIL
+ //to avoid the ISR handler function crashing when the cache is disabled.
+ if( (p_i2c_obj[i2c_num]->intr_alloc_flags & ESP_INTR_FLAG_IRAM) ) {
+ if( !is_cmd_link_buffer_internal(((i2c_cmd_desc_t*)cmd_handle)->head) ) {
+ ESP_LOGE(I2C_TAG, I2C_PSRAM_BUFFER_WARN_STR);
+ return ESP_ERR_INVALID_ARG;
+ }
+ }
+#endif
+ // Sometimes when the FSM get stuck, the ACK_ERR interrupt will occur endlessly until we reset the FSM and clear bus.
+ static uint8_t clear_bus_cnt = 0;
+ esp_err_t ret = ESP_FAIL;
+ i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
+ portTickType ticks_start = xTaskGetTickCount();
+ portBASE_TYPE res = xSemaphoreTake(p_i2c->cmd_mux, ticks_to_wait);
+ if (res == pdFALSE) {
+ return ESP_ERR_TIMEOUT;
+ }
+ xQueueReset(p_i2c->cmd_evt_queue);
+ if (p_i2c->status == I2C_STATUS_TIMEOUT
+ || I2C[i2c_num]->status_reg.bus_busy == 1) {
+ i2c_hw_fsm_reset(i2c_num);
+ clear_bus_cnt = 0;
+ }
+ i2c_reset_tx_fifo(i2c_num);
+ i2c_reset_rx_fifo(i2c_num);
+ i2c_cmd_desc_t* cmd = (i2c_cmd_desc_t*) cmd_handle;
+ p_i2c->cmd_link.free = cmd->free;
+ p_i2c->cmd_link.cur = cmd->cur;
+ p_i2c->cmd_link.head = cmd->head;
+ p_i2c->status = I2C_STATUS_IDLE;
+ p_i2c->cmd_idx = 0;
+ p_i2c->rx_cnt = 0;
+ p_i2c->tx_fifo_remain = I2C_FIFO_LEN;
+ p_i2c->rx_fifo_remain = I2C_FIFO_LEN;
+ i2c_reset_tx_fifo(i2c_num);
+ i2c_reset_rx_fifo(i2c_num);
+ // These two interrupts some times can not be cleared when the FSM gets stuck.
+ // so we disable them when these two interrupt occurs and re-enable them here.
+ I2C[i2c_num]->int_ena.ack_err = 1;
+ I2C[i2c_num]->int_ena.time_out = 1;
+ //start send commands, at most 32 bytes one time, isr handler will process the remaining commands.
+ i2c_master_cmd_begin_static(i2c_num);
+
+ // Wait event bits
+ i2c_cmd_evt_t evt;
+ while (1) {
+ TickType_t wait_time = xTaskGetTickCount();
+ if (wait_time - ticks_start > ticks_to_wait) { // out of time
+ wait_time = I2C_CMD_ALIVE_INTERVAL_TICK;
+ } else {
+ wait_time = ticks_to_wait - (wait_time - ticks_start);
+ if (wait_time < I2C_CMD_ALIVE_INTERVAL_TICK) {
+ wait_time = I2C_CMD_ALIVE_INTERVAL_TICK;
+ }
+ }
+ // In master mode, since we don't have an interrupt to detective bus error or FSM state, what we do here is to make
+ // sure the interrupt mechanism for master mode is still working.
+ // If the command sending is not finished and there is no interrupt any more, the bus is probably dead caused by external noise.
+ portBASE_TYPE evt_res = xQueueReceive(p_i2c->cmd_evt_queue, &evt, wait_time);
+ if (evt_res == pdTRUE) {
+ if (evt.type == I2C_CMD_EVT_DONE) {
+ if (p_i2c->status == I2C_STATUS_TIMEOUT) {
+ // If the I2C slave are powered off or the SDA/SCL are connected to ground, for example,
+ // I2C hw FSM would get stuck in wrong state, we have to reset the I2C module in this case.
+ i2c_hw_fsm_reset(i2c_num);
+ clear_bus_cnt = 0;
+ ret = ESP_ERR_TIMEOUT;
+ } else if (p_i2c->status == I2C_STATUS_ACK_ERROR) {
+ clear_bus_cnt++;
+ if(clear_bus_cnt >= I2C_ACKERR_CNT_MAX) {
+ i2c_master_clear_bus(i2c_num);
+ clear_bus_cnt = 0;
+ }
+ ret = ESP_FAIL;
+ } else {
+ ret = ESP_OK;
+ }
+ break;
+ }
+ if (evt.type == I2C_CMD_EVT_ALIVE) {
+ }
+ } else {
+ ret = ESP_ERR_TIMEOUT;
+ // If the I2C slave are powered off or the SDA/SCL are connected to ground, for example,
+ // I2C hw FSM would get stuck in wrong state, we have to reset the I2C module in this case.
+ i2c_hw_fsm_reset(i2c_num);
+ clear_bus_cnt = 0;
+ break;
+ }
+ }
+ p_i2c->status = I2C_STATUS_DONE;
+ xSemaphoreGive(p_i2c->cmd_mux);
+ return ret;
+}
+
+int i2c_slave_write_buffer(i2c_port_t i2c_num, uint8_t* data, int size, TickType_t ticks_to_wait)
+{
+ I2C_CHECK(( i2c_num < I2C_NUM_MAX ), I2C_NUM_ERROR_STR, ESP_FAIL);
+ I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_FAIL);
+ I2C_CHECK(p_i2c_obj[i2c_num]->mode == I2C_MODE_SLAVE, I2C_MODE_SLAVE_ERR_STR, ESP_FAIL);
+ i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
+
+ portBASE_TYPE res;
+ int cnt = 0;
+ portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait;
+
+ res = xSemaphoreTake(p_i2c->slv_tx_mux, ticks_to_wait);
+ if (res == pdFALSE) {
+ return 0;
+ }
+ ticks_to_wait = ticks_end - xTaskGetTickCount();
+ res = xRingbufferSend(p_i2c->tx_ring_buf, data, size, ticks_to_wait);
+ if (res == pdFALSE) {
+ cnt = 0;
+ } else {
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ I2C[i2c_num]->int_clr.tx_fifo_empty = 1;
+ I2C[i2c_num]->int_ena.tx_fifo_empty = 1;
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ cnt = size;
+ }
+ xSemaphoreGive(p_i2c->slv_tx_mux);
+ return cnt;
+}
+
+static int i2c_slave_read(i2c_port_t i2c_num, uint8_t* data, size_t max_size, TickType_t ticks_to_wait)
+{
+ i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
+ size_t size = 0;
+ uint8_t* pdata = (uint8_t*) xRingbufferReceiveUpTo(p_i2c->rx_ring_buf, &size, ticks_to_wait, max_size);
+ if (pdata && size > 0) {
+ memcpy(data, pdata, size);
+ vRingbufferReturnItem(p_i2c->rx_ring_buf, pdata);
+ }
+ return size;
+}
+
+int i2c_slave_read_buffer(i2c_port_t i2c_num, uint8_t* data, size_t max_size, TickType_t ticks_to_wait)
+{
+ I2C_CHECK(( i2c_num < I2C_NUM_MAX ), I2C_NUM_ERROR_STR, ESP_FAIL);
+ I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_FAIL);
+ I2C_CHECK(p_i2c_obj[i2c_num]->mode == I2C_MODE_SLAVE, I2C_MODE_SLAVE_ERR_STR, ESP_FAIL);
+
+ i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];
+ portBASE_TYPE res;
+ portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait;
+ res = xSemaphoreTake(p_i2c->slv_rx_mux, ticks_to_wait);
+ if (res == pdFALSE) {
+ return 0;
+ }
+ ticks_to_wait = ticks_end - xTaskGetTickCount();
+ int cnt = i2c_slave_read(i2c_num, data, max_size, ticks_to_wait);
+ if (cnt > 0) {
+ I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
+ I2C[i2c_num]->int_ena.rx_fifo_full = 1;
+ I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
+ ticks_to_wait = ticks_end - xTaskGetTickCount();
+ if (cnt < max_size && ticks_to_wait > 0) {
+ cnt += i2c_slave_read(i2c_num, data + cnt, max_size - cnt, ticks_to_wait);
+ }
+ } else {
+ cnt = 0;
+ }
+ xSemaphoreGive(p_i2c->slv_rx_mux);
+ return cnt;
+}
diff --git a/components/driver/include/driver/can.h b/components/driver/include/driver/can.h
new file mode 100644
index 0000000000..5ec272ca47
--- /dev/null
+++ b/components/driver/include/driver/can.h
@@ -0,0 +1,398 @@
+// Copyright 2015-2018 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.
+
+#ifndef _DRIVER_CAN_H_
+#define _DRIVER_CAN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "esp_types.h"
+#include "esp_intr.h"
+#include "esp_err.h"
+#include "gpio.h"
+
+/* -------------------- Default initializers and flags ---------------------- */
+/** @cond */ //Doxy command to hide preprocessor definitions from docs
+/**
+ * @brief Initializer macro for general configuration structure.
+ *
+ * This initializer macros allows the TX GPIO, RX GPIO, and operating mode to be
+ * configured. The other members of the general configuration structure are
+ * assigned default values.
+ */
+#define CAN_GENERAL_CONFIG_DEFAULT(tx_io_num, rx_io_num, op_mode) {.mode = op_mode, .tx_io = tx_io_num, .rx_io = rx_io_num, \
+ .clkout_io = CAN_IO_UNUSED, .bus_off_io = CAN_IO_UNUSED, \
+ .tx_queue_len = 5, .rx_queue_len = 5, \
+ .alerts_enabled = CAN_ALERT_NONE, .clkout_divider = 0, }
+
+/**
+ * @brief Initializer macros for timing configuration structure
+ *
+ * The following initializer macros offer commonly found bit rates.
+ */
+#define CAN_TIMING_CONFIG_25KBITS() {.brp = 128, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
+#define CAN_TIMING_CONFIG_50KBITS() {.brp = 80, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
+#define CAN_TIMING_CONFIG_100KBITS() {.brp = 40, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
+#define CAN_TIMING_CONFIG_125KBITS() {.brp = 32, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
+#define CAN_TIMING_CONFIG_250KBITS() {.brp = 16, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
+#define CAN_TIMING_CONFIG_500KBITS() {.brp = 8, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
+#define CAN_TIMING_CONFIG_800KBITS() {.brp = 4, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
+#define CAN_TIMING_CONFIG_1MBITS() {.brp = 4, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
+
+/**
+ * @brief Initializer macro for filter configuration to accept all IDs
+ */
+#define CAN_FILTER_CONFIG_ACCEPT_ALL() {.acceptance_code = 0, .acceptance_mask = 0xFFFFFFFF, .single_filter = true}
+
+/**
+ * @brief Alert flags
+ *
+ * The following flags represents the various kind of alerts available in
+ * the CAN driver. These flags can be used when configuring/reconfiguring
+ * alerts, or when calling can_read_alerts().
+ *
+ * @note The CAN_ALERT_AND_LOG flag is not an actual alert, but will configure
+ * the CAN driver to log to UART when an enabled alert occurs.
+ */
+#define CAN_ALERT_TX_IDLE 0x0001 /**< Alert(1): No more messages to transmit */
+#define CAN_ALERT_TX_SUCCESS 0x0002 /**< Alert(2): The previous transmission was successful */
+#define CAN_ALERT_BELOW_ERR_WARN 0x0004 /**< Alert(4): Both error counters have dropped below error warning limit */
+#define CAN_ALERT_ERR_ACTIVE 0x0008 /**< Alert(8): CAN controller has become error active */
+#define CAN_ALERT_RECOVERY_IN_PROGRESS 0x0010 /**< Alert(16): CAN controller is undergoing bus recovery */
+#define CAN_ALERT_BUS_RECOVERED 0x0020 /**< Alert(32): CAN controller has successfully completed bus recovery */
+#define CAN_ALERT_ARB_LOST 0x0040 /**< Alert(64): The previous transmission lost arbitration */
+#define CAN_ALERT_ABOVE_ERR_WARN 0x0080 /**< Alert(128): One of the error counters have exceeded the error warning limit */
+#define CAN_ALERT_BUS_ERROR 0x0100 /**< Alert(256): A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus */
+#define CAN_ALERT_TX_FAILED 0x0200 /**< Alert(512): The previous transmission has failed (for single shot transmission) */
+#define CAN_ALERT_RX_QUEUE_FULL 0x0400 /**< Alert(1024): The RX queue is full causing a frame to be lost */
+#define CAN_ALERT_ERR_PASS 0x0800 /**< Alert(2048): CAN controller has become error passive */
+#define CAN_ALERT_BUS_OFF 0x1000 /**< Alert(4096): Bus-off condition occurred. CAN controller can no longer influence bus */
+#define CAN_ALERT_ALL 0x1FFF /**< Bit mask to enable all alerts during configuration */
+#define CAN_ALERT_NONE 0x0000 /**< Bit mask to disable all alerts during configuration */
+#define CAN_ALERT_AND_LOG 0x2000 /**< Bit mask to enable alerts to also be logged when they occur */
+
+/**
+ * @brief Message flags
+ *
+ * The message flags are used to indicate the type of message transmitted/received.
+ * Some flags also specify the type of transmission.
+ */
+#define CAN_MSG_FLAG_NONE 0x00 /**< No message flags (Standard Frame Format) */
+#define CAN_MSG_FLAG_EXTD 0x01 /**< Extended Frame Format (29bit ID) */
+#define CAN_MSG_FLAG_RTR 0x02 /**< Message is a Remote Transmit Request */
+#define CAN_MSG_FLAG_SS 0x04 /**< Transmit as a Single Shot Transmission */
+#define CAN_MSG_FLAG_SELF 0x08 /**< Transmit as a Self Reception Request */
+#define CAN_MSG_FLAG_DLC_NON_COMP 0x10 /**< Message's Data length code is larger than 8. This will break compliance with CAN2.0B */
+
+/**
+ * @brief Miscellaneous macros
+ */
+#define CAN_EXTD_ID_MASK 0x1FFFFFFF /**< Bit mask for 29 bit Extended Frame Format ID */
+#define CAN_STD_ID_MASK 0x7FF /**< Bit mask for 11 bit Standard Frame Format ID */
+#define CAN_MAX_DATA_LEN 8 /**< Maximum number of data bytes in a CAN2.0B frame */
+#define CAN_IO_UNUSED (-1) /**< Marks GPIO as unused in CAN configuration */
+/** @endcond */
+
+/* ----------------------- Enum and Struct Definitions ---------------------- */
+
+/**
+ * @brief CAN driver operating modes
+ */
+typedef enum {
+ CAN_MODE_NORMAL, /**< Normal operating mode where CAN controller can send/receive/acknowledge messages */
+ CAN_MODE_NO_ACK, /**< Transmission does not require acknowledgment. Use this mode for self testing */
+ CAN_MODE_LISTEN_ONLY, /**< The CAN controller will not influence the bus (No transmissions or acknowledgments) but can receive messages */
+} can_mode_t;
+
+/**
+ * @brief CAN driver states
+ */
+typedef enum {
+ CAN_STATE_STOPPED, /**< Stopped state. The CAN controller will not participate in any CAN bus activities */
+ CAN_STATE_RUNNING, /**< Running state. The CAN controller can transmit and receive messages */
+ CAN_STATE_BUS_OFF, /**< Bus-off state. The CAN controller cannot participate in bus activities until it has recovered */
+ CAN_STATE_RECOVERING, /**< Recovering state. The CAN controller is undergoing bus recovery */
+} can_state_t;
+
+/**
+ * @brief Structure for general configuration of the CAN driver
+ *
+ * @note Macro initializers are available for this structure
+ */
+typedef struct {
+ can_mode_t mode; /**< Mode of CAN controller */
+ gpio_num_t tx_io; /**< Transmit GPIO number */
+ gpio_num_t rx_io; /**< Receive GPIO number */
+ gpio_num_t clkout_io; /**< CLKOUT GPIO number (optional, set to -1 if unused) */
+ gpio_num_t bus_off_io; /**< Bus off indicator GPIO number (optional, set to -1 if unused) */
+ uint32_t tx_queue_len; /**< Number of messages TX queue can hold (set to 0 to disable TX Queue) */
+ uint32_t rx_queue_len; /**< Number of messages RX queue can hold */
+ uint32_t alerts_enabled; /**< Bit field of alerts to enable (see documentation) */
+ uint32_t clkout_divider; /**< CLKOUT divider. Can be 1 or any even number from 2 to 14 (optional, set to 0 if unused) */
+} can_general_config_t;
+
+/**
+ * @brief Structure for bit timing configuration of the CAN driver
+ *
+ * @note Macro initializers are available for this structure
+ */
+typedef struct {
+ uint8_t brp; /**< Baudrate prescaler (APB clock divider, even number from 2 to 128) */
+ uint8_t tseg_1; /**< Timing segment 1 (Number of time quanta, between 1 to 16) */
+ uint8_t tseg_2; /**< Timing segment 2 (Number of time quanta, 1 to 8) */
+ uint8_t sjw; /**< Synchronization Jump Width (Max time quanta jump for synchronize from 1 to 4) */
+ bool triple_sampling; /**< Enables triple sampling when the CAN controller samples a bit */
+} can_timing_config_t;
+
+/**
+ * @brief Structure for acceptance filter configuration of the CAN driver (see documentation)
+ *
+ * @note Macro initializers are available for this structure
+ */
+typedef struct {
+ uint32_t acceptance_code; /**< 32-bit acceptance code */
+ uint32_t acceptance_mask; /**< 32-bit acceptance mask */
+ bool single_filter; /**< Use Single Filter Mode (see documentation) */
+} can_filter_config_t;
+
+/**
+ * @brief Structure to store status information of CAN driver
+ */
+typedef struct {
+ can_state_t state; /**< Current state of CAN controller (Stopped/Running/Bus-Off/Recovery) */
+ uint32_t msgs_to_tx; /**< Number of messages queued for transmission or awaiting transmission completion */
+ uint32_t msgs_to_rx; /**< Number of messages in RX queue waiting to be read */
+ uint32_t tx_error_counter; /**< Current value of Transmit Error Counter */
+ uint32_t rx_error_counter; /**< Current value of Receive Error Counter */
+ uint32_t tx_failed_count; /**< Number of messages that failed transmissions */
+ uint32_t rx_missed_count; /**< Number of messages that were lost due to a full RX queue */
+ uint32_t arb_lost_count; /**< Number of instances arbitration was lost */
+ uint32_t bus_error_count; /**< Number of instances a bus error has occurred */
+} can_status_info_t;
+
+/**
+ * @brief Structure to store a CAN message
+ *
+ * @note The flags member is used to control the message type, and transmission
+ * type (see documentation for message flags)
+ */
+typedef struct {
+ uint32_t flags; /**< Bit field of message flags indicates frame/transmission type (see documentation) */
+ uint32_t identifier; /**< 11 or 29 bit identifier */
+ uint8_t data_length_code; /**< Data length code */
+ uint8_t data[CAN_MAX_DATA_LEN]; /**< Data bytes (not relevant in RTR frame) */
+} can_message_t;
+
+/* ----------------------------- Public API -------------------------------- */
+
+/**
+ * @brief Install CAN driver
+ *
+ * This function installs the CAN driver using three configuration structures.
+ * The required memory is allocated and the CAN driver is placed in the stopped
+ * state after running this function.
+ *
+ * @param[in] g_config General configuration structure
+ * @param[in] t_config Timing configuration structure
+ * @param[in] f_config Filter configuration structure
+ *
+ * @note Macro initializers are available for the configuration structures (see documentation)
+ *
+ * @note To reinstall the CAN driver, call can_driver_uninstall() first
+ *
+ * @return
+ * - ESP_OK: Successfully installed CAN driver
+ * - ESP_ERR_INVALID_ARG: Arguments are invalid
+ * - ESP_ERR_NO_MEM: Insufficient memory
+ * - ESP_ERR_INVALID_STATE: Driver is already installed
+ */
+esp_err_t can_driver_install(const can_general_config_t *g_config, const can_timing_config_t *t_config, const can_filter_config_t *f_config);
+
+/**
+ * @brief Uninstall the CAN driver
+ *
+ * This function uninstalls the CAN driver, freeing the memory utilized by the
+ * driver. This function can only be called when the driver is in the stopped
+ * state or the bus-off state.
+ *
+ * @warning The application must ensure that no tasks are blocked on TX/RX
+ * queues or alerts when this function is called.
+ *
+ * @return
+ * - ESP_OK: Successfully uninstalled CAN driver
+ * - ESP_ERR_INVALID_STATE: Driver is not in stopped/bus-off state, or is not installed
+ */
+esp_err_t can_driver_uninstall();
+
+/**
+ * @brief Start the CAN driver
+ *
+ * This function starts the CAN driver, putting the CAN driver into the running
+ * state. This allows the CAN driver to participate in CAN bus activities such
+ * as transmitting/receiving messages. The RX queue is reset in this function,
+ * clearing any unread messages. This function can only be called when the CAN
+ * driver is in the stopped state.
+ *
+ * @return
+ * - ESP_OK: CAN driver is now running
+ * - ESP_ERR_INVALID_STATE: Driver is not in stopped state, or is not installed
+ */
+esp_err_t can_start();
+
+/**
+ * @brief Stop the CAN driver
+ *
+ * This function stops the CAN driver, preventing any further message from being
+ * transmitted or received until can_start() is called. Any messages in the TX
+ * queue are cleared. Any messages in the RX queue should be read by the
+ * application after this function is called. This function can only be called
+ * when the CAN driver is in the running state.
+ *
+ * @warning A message currently being transmitted/received on the CAN bus will
+ * be ceased immediately. This may lead to other CAN nodes interpreting
+ * the unfinished message as an error.
+ *
+ * @return
+ * - ESP_OK: CAN driver is now Stopped
+ * - ESP_ERR_INVALID_STATE: Driver is not in running state, or is not installed
+ */
+esp_err_t can_stop();
+
+/**
+ * @brief Transmit a CAN message
+ *
+ * This function queues a CAN message for transmission. Transmission will start
+ * immediately if no other messages are queued for transmission. If the TX queue
+ * is full, this function will block until more space becomes available or until
+ * it timesout. If the TX queue is disabled (TX queue length = 0 in configuration),
+ * this function will return immediately if another message is undergoing
+ * transmission. This function can only be called when the CAN driver is in the
+ * running state and cannot be called under Listen Only Mode.
+ *
+ * @param[in] message Message to transmit
+ * @param[in] ticks_to_wait Number of FreeRTOS ticks to block on the TX queue
+ *
+ * @note This function does not guarantee that the transmission is successful.
+ * The TX_SUCCESS/TX_FAILED alert can be enabled to alert the application
+ * upon the success/failure of a transmission.
+ *
+ * @note The TX_IDLE alert can be used to alert the application when no other
+ * messages are awaiting transmission.
+ *
+ * @return
+ * - ESP_OK: Transmission successfully queued/initiated
+ * - ESP_ERR_INVALID_ARG: Arguments are invalid
+ * - ESP_ERR_TIMEOUT: Timed out waiting for space on TX queue
+ * - ESP_FAIL: TX queue is disabled and another message is currently transmitting
+ * - ESP_ERR_INVALID_STATE: CAN driver is not in running state, or is not installed
+ * - ESP_ERR_NOT_SUPPORTED: Listen Only Mode does not support transmissions
+ */
+esp_err_t can_transmit(const can_message_t *message, TickType_t ticks_to_wait);
+
+/**
+ * @brief Receive a CAN message
+ *
+ * This function receives a message from the RX queue. The flags field of the
+ * message structure will indicate the type of message received. This function
+ * will block if there are no messages in the RX queue
+ *
+ * @param[out] message Received message
+ * @param[in] ticks_to_wait Number of FreeRTOS ticks to block on RX queue
+ *
+ * @warning The flags field of the received message should be checked to determine
+ * if the received message contains any data bytes.
+ *
+ * @return
+ * - ESP_OK: Message successfully received from RX queue
+ * - ESP_ERR_TIMEOUT: Timed out waiting for message
+ * - ESP_ERR_INVALID_ARG: Arguments are invalid
+ * - ESP_ERR_INVALID_STATE: CAN driver is not installed
+ */
+esp_err_t can_receive(can_message_t *message, TickType_t ticks_to_wait);
+
+/**
+ * @brief Read CAN driver alerts
+ *
+ * This function will read the alerts raised by the CAN driver. If no alert has
+ * been when this function is called, this function will block until an alert
+ * occurs or until it timeouts.
+ *
+ * @param[out] alerts Bit field of raised alerts (see documentation for alert flags)
+ * @param[in] ticks_to_wait Number of FreeRTOS ticks to block for alert
+ *
+ * @note Multiple alerts can be raised simultaneously. The application should
+ * check for all alerts that have been enabled.
+ *
+ * @return
+ * - ESP_OK: Alerts read
+ * - ESP_ERR_TIMEOUT: Timed out waiting for alerts
+ * - ESP_ERR_INVALID_ARG: Arguments are invalid
+ * - ESP_ERR_INVALID_STATE: CAN driver is not installed
+ */
+esp_err_t can_read_alerts(uint32_t *alerts, TickType_t ticks_to_wait);
+
+/**
+ * @brief Reconfigure which alerts are enabled
+ *
+ * This function reconfigures which alerts are enabled. If there are alerts
+ * which have not been read whilst reconfiguring, this function can read those
+ * alerts.
+ *
+ * @param[in] alerts_enabled Bit field of alerts to enable (see documentation for alert flags)
+ * @param[out] current_alerts Bit field of currently raised alerts. Set to NULL if unused
+ *
+ * @return
+ * - ESP_OK: Alerts reconfigured
+ * - ESP_ERR_INVALID_STATE: CAN driver is not installed
+ */
+esp_err_t can_reconfigure_alerts(uint32_t alerts_enabled, uint32_t *current_alerts);
+
+/**
+ * @brief Start the bus recovery process
+ *
+ * This function initiates the bus recovery process when the CAN driver is in
+ * the bus-off state. Once initiated, the CAN driver will enter the recovering
+ * state and wait for 128 occurrences of the bus-free signal on the CAN bus
+ * before returning to the stopped state. This function will reset the TX queue,
+ * clearing any messages pending transmission.
+ *
+ * @note The BUS_RECOVERED alert can be enabled to alert the application when
+ * the bus recovery process completes.
+ *
+ * @return
+ * - ESP_OK: Bus recovery started
+ * - ESP_ERR_INVALID_STATE: CAN driver is not in the bus-off state, or is not installed
+ */
+esp_err_t can_initiate_recovery();
+
+/**
+ * @brief Get current status information of the CAN driver
+ *
+ * @param[out] status_info Status information
+ *
+ * @return
+ * - ESP_OK: Status information retrieved
+ * - ESP_ERR_INVALID_ARG: Arguments are invalid
+ * - ESP_ERR_INVALID_STATE: CAN driver is not installed
+ */
+esp_err_t can_get_status_info(can_status_info_t *status_info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_DRIVER_CAN_H_*/
+
diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h
index f8aa33abf9..bc8436491d 100644
--- a/components/driver/include/driver/gpio.h
+++ b/components/driver/include/driver/gpio.h
@@ -24,6 +24,7 @@
#include "rom/gpio.h"
#include "esp_attr.h"
#include "esp_intr_alloc.h"
+#include "soc/gpio_periph.h"
#ifdef __cplusplus
extern "C" {
@@ -121,10 +122,8 @@ extern "C" {
#define GPIO_MODE_DEF_OD (BIT2)
-#define GPIO_PIN_COUNT 40
/** @endcond */
-extern const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT];
#define GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num < GPIO_PIN_COUNT && GPIO_PIN_MUX_REG[gpio_num] != 0)) /*!< Check whether it is a valid GPIO number */
#define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((GPIO_IS_VALID_GPIO(gpio_num)) && (gpio_num < 34)) /*!< Check whether it can be a valid GPIO number of output mode */
@@ -248,6 +247,18 @@ typedef intr_handle_t gpio_isr_handle_t;
*/
esp_err_t gpio_config(const gpio_config_t *pGPIOConfig);
+/**
+ * @brief Reset an gpio to default state (select gpio function, enable pullup and disable input and output).
+ *
+ * @param gpio_num GPIO number.
+ *
+ * @note This function also configures the IOMUX for this pin to the GPIO
+ * function, and disconnects any other peripheral output configured via GPIO
+ * Matrix.
+ *
+ * @return Always return ESP_OK.
+ */
+esp_err_t gpio_reset_pin(gpio_num_t gpio_num);
/**
* @brief GPIO set interrupt trigger type
diff --git a/components/driver/include/driver/i2c.h b/components/driver/include/driver/i2c.h
index 0f892db5e7..8f8cb9a148 100644
--- a/components/driver/include/driver/i2c.h
+++ b/components/driver/include/driver/i2c.h
@@ -1,550 +1,550 @@
-// Copyright 2015-2016 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.
-
-#ifndef _DRIVER_I2C_H_
-#define _DRIVER_I2C_H_
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include
-#include "esp_err.h"
-#include "esp_intr_alloc.h"
-#include "freertos/FreeRTOS.h"
-#include "freertos/semphr.h"
-#include "freertos/xtensa_api.h"
-#include "freertos/task.h"
-#include "freertos/queue.h"
-#include "freertos/ringbuf.h"
-#include "driver/gpio.h"
-
-#define I2C_APB_CLK_FREQ APB_CLK_FREQ /*!< I2C source clock is APB clock, 80MHz */
-#define I2C_FIFO_LEN (32) /*!< I2C hardware fifo length */
-typedef enum{
- I2C_MODE_SLAVE = 0, /*!< I2C slave mode */
- I2C_MODE_MASTER, /*!< I2C master mode */
- I2C_MODE_MAX,
-}i2c_mode_t;
-
-typedef enum {
- I2C_MASTER_WRITE = 0, /*!< I2C write data */
- I2C_MASTER_READ, /*!< I2C read data */
-} i2c_rw_t;
-
-typedef enum {
- I2C_DATA_MODE_MSB_FIRST = 0, /*!< I2C data msb first */
- I2C_DATA_MODE_LSB_FIRST = 1, /*!< I2C data lsb first */
- I2C_DATA_MODE_MAX
-} i2c_trans_mode_t;
-
-typedef enum{
- I2C_CMD_RESTART = 0, /*!=0) The number of data bytes that pushed to the I2C slave buffer.
- */
-int i2c_slave_write_buffer(i2c_port_t i2c_num, uint8_t* data, int size, TickType_t ticks_to_wait);
-
-/**
- * @brief I2C slave read data from internal buffer. When I2C slave receive data, isr will copy received data
- * from hardware rx fifo to internal ringbuffer. Then users can read from internal ringbuffer.
- * @note
- * Only call this function in I2C slave mode
- *
- * @param i2c_num I2C port number
- * @param data data pointer to write into internal buffer
- * @param max_size Maximum data size to read
- * @param ticks_to_wait Maximum waiting ticks
- *
- * @return
- * - ESP_FAIL(-1) Parameter error
- * - Others(>=0) The number of data bytes that read from I2C slave buffer.
- */
-int i2c_slave_read_buffer(i2c_port_t i2c_num, uint8_t* data, size_t max_size, TickType_t ticks_to_wait);
-
-/**
- * @brief set I2C master clock period
- *
- * @param i2c_num I2C port number
- * @param high_period clock cycle number during SCL is high level, high_period is a 14 bit value
- * @param low_period clock cycle number during SCL is low level, low_period is a 14 bit value
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- */
-esp_err_t i2c_set_period(i2c_port_t i2c_num, int high_period, int low_period);
-
-/**
- * @brief get I2C master clock period
- *
- * @param i2c_num I2C port number
- * @param high_period pointer to get clock cycle number during SCL is high level, will get a 14 bit value
- * @param low_period pointer to get clock cycle number during SCL is low level, will get a 14 bit value
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- */
-esp_err_t i2c_get_period(i2c_port_t i2c_num, int* high_period, int* low_period);
-
-/**
- * @brief set I2C master start signal timing
- *
- * @param i2c_num I2C port number
- * @param setup_time clock number between the falling-edge of SDA and rising-edge of SCL for start mark, it's a 10-bit value.
- * @param hold_time clock num between the falling-edge of SDA and falling-edge of SCL for start mark, it's a 10-bit value.
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- */
-esp_err_t i2c_set_start_timing(i2c_port_t i2c_num, int setup_time, int hold_time);
-
-/**
- * @brief get I2C master start signal timing
- *
- * @param i2c_num I2C port number
- * @param setup_time pointer to get setup time
- * @param hold_time pointer to get hold time
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- */
-esp_err_t i2c_get_start_timing(i2c_port_t i2c_num, int* setup_time, int* hold_time);
-
-/**
- * @brief set I2C master stop signal timing
- *
- * @param i2c_num I2C port number
- * @param setup_time clock num between the rising-edge of SCL and the rising-edge of SDA, it's a 10-bit value.
- * @param hold_time clock number after the STOP bit's rising-edge, it's a 14-bit value.
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- */
-esp_err_t i2c_set_stop_timing(i2c_port_t i2c_num, int setup_time, int hold_time);
-
-/**
- * @brief get I2C master stop signal timing
- *
- * @param i2c_num I2C port number
- * @param setup_time pointer to get setup time.
- * @param hold_time pointer to get hold time.
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- */
-esp_err_t i2c_get_stop_timing(i2c_port_t i2c_num, int* setup_time, int* hold_time);
-
-/**
- * @brief set I2C data signal timing
- *
- * @param i2c_num I2C port number
- * @param sample_time clock number I2C used to sample data on SDA after the rising-edge of SCL, it's a 10-bit value
- * @param hold_time clock number I2C used to hold the data after the falling-edge of SCL, it's a 10-bit value
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- */
-esp_err_t i2c_set_data_timing(i2c_port_t i2c_num, int sample_time, int hold_time);
-
-/**
- * @brief get I2C data signal timing
- *
- * @param i2c_num I2C port number
- * @param sample_time pointer to get sample time
- * @param hold_time pointer to get hold time
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- */
-esp_err_t i2c_get_data_timing(i2c_port_t i2c_num, int* sample_time, int* hold_time);
-
-/**
- * @brief set I2C timeout value
- * @param i2c_num I2C port number
- * @param timeout timeout value for I2C bus (unit: APB 80Mhz clock cycle)
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- */
-esp_err_t i2c_set_timeout(i2c_port_t i2c_num, int timeout);
-
-/**
- * @brief get I2C timeout value
- * @param i2c_num I2C port number
- * @param timeout pointer to get timeout value
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- */
-esp_err_t i2c_get_timeout(i2c_port_t i2c_num, int* timeout);
-/**
- * @brief set I2C data transfer mode
- *
- * @param i2c_num I2C port number
- * @param tx_trans_mode I2C sending data mode
- * @param rx_trans_mode I2C receving data mode
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- */
-esp_err_t i2c_set_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t tx_trans_mode, i2c_trans_mode_t rx_trans_mode);
-
-/**
- * @brief get I2C data transfer mode
- *
- * @param i2c_num I2C port number
- * @param tx_trans_mode pointer to get I2C sending data mode
- * @param rx_trans_mode pointer to get I2C receiving data mode
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- */
-esp_err_t i2c_get_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t *tx_trans_mode, i2c_trans_mode_t *rx_trans_mode);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*_DRIVER_I2C_H_*/
+// Copyright 2015-2016 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.
+
+#ifndef _DRIVER_I2C_H_
+#define _DRIVER_I2C_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include
+#include "esp_err.h"
+#include "esp_intr_alloc.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/semphr.h"
+#include "freertos/xtensa_api.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "freertos/ringbuf.h"
+#include "driver/gpio.h"
+
+#define I2C_APB_CLK_FREQ APB_CLK_FREQ /*!< I2C source clock is APB clock, 80MHz */
+#define I2C_FIFO_LEN (32) /*!< I2C hardware fifo length */
+typedef enum{
+ I2C_MODE_SLAVE = 0, /*!< I2C slave mode */
+ I2C_MODE_MASTER, /*!< I2C master mode */
+ I2C_MODE_MAX,
+}i2c_mode_t;
+
+typedef enum {
+ I2C_MASTER_WRITE = 0, /*!< I2C write data */
+ I2C_MASTER_READ, /*!< I2C read data */
+} i2c_rw_t;
+
+typedef enum {
+ I2C_DATA_MODE_MSB_FIRST = 0, /*!< I2C data msb first */
+ I2C_DATA_MODE_LSB_FIRST = 1, /*!< I2C data lsb first */
+ I2C_DATA_MODE_MAX
+} i2c_trans_mode_t;
+
+typedef enum{
+ I2C_CMD_RESTART = 0, /*!=0) The number of data bytes that pushed to the I2C slave buffer.
+ */
+int i2c_slave_write_buffer(i2c_port_t i2c_num, uint8_t* data, int size, TickType_t ticks_to_wait);
+
+/**
+ * @brief I2C slave read data from internal buffer. When I2C slave receive data, isr will copy received data
+ * from hardware rx fifo to internal ringbuffer. Then users can read from internal ringbuffer.
+ * @note
+ * Only call this function in I2C slave mode
+ *
+ * @param i2c_num I2C port number
+ * @param data data pointer to write into internal buffer
+ * @param max_size Maximum data size to read
+ * @param ticks_to_wait Maximum waiting ticks
+ *
+ * @return
+ * - ESP_FAIL(-1) Parameter error
+ * - Others(>=0) The number of data bytes that read from I2C slave buffer.
+ */
+int i2c_slave_read_buffer(i2c_port_t i2c_num, uint8_t* data, size_t max_size, TickType_t ticks_to_wait);
+
+/**
+ * @brief set I2C master clock period
+ *
+ * @param i2c_num I2C port number
+ * @param high_period clock cycle number during SCL is high level, high_period is a 14 bit value
+ * @param low_period clock cycle number during SCL is low level, low_period is a 14 bit value
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t i2c_set_period(i2c_port_t i2c_num, int high_period, int low_period);
+
+/**
+ * @brief get I2C master clock period
+ *
+ * @param i2c_num I2C port number
+ * @param high_period pointer to get clock cycle number during SCL is high level, will get a 14 bit value
+ * @param low_period pointer to get clock cycle number during SCL is low level, will get a 14 bit value
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t i2c_get_period(i2c_port_t i2c_num, int* high_period, int* low_period);
+
+/**
+ * @brief set I2C master start signal timing
+ *
+ * @param i2c_num I2C port number
+ * @param setup_time clock number between the falling-edge of SDA and rising-edge of SCL for start mark, it's a 10-bit value.
+ * @param hold_time clock num between the falling-edge of SDA and falling-edge of SCL for start mark, it's a 10-bit value.
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t i2c_set_start_timing(i2c_port_t i2c_num, int setup_time, int hold_time);
+
+/**
+ * @brief get I2C master start signal timing
+ *
+ * @param i2c_num I2C port number
+ * @param setup_time pointer to get setup time
+ * @param hold_time pointer to get hold time
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t i2c_get_start_timing(i2c_port_t i2c_num, int* setup_time, int* hold_time);
+
+/**
+ * @brief set I2C master stop signal timing
+ *
+ * @param i2c_num I2C port number
+ * @param setup_time clock num between the rising-edge of SCL and the rising-edge of SDA, it's a 10-bit value.
+ * @param hold_time clock number after the STOP bit's rising-edge, it's a 14-bit value.
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t i2c_set_stop_timing(i2c_port_t i2c_num, int setup_time, int hold_time);
+
+/**
+ * @brief get I2C master stop signal timing
+ *
+ * @param i2c_num I2C port number
+ * @param setup_time pointer to get setup time.
+ * @param hold_time pointer to get hold time.
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t i2c_get_stop_timing(i2c_port_t i2c_num, int* setup_time, int* hold_time);
+
+/**
+ * @brief set I2C data signal timing
+ *
+ * @param i2c_num I2C port number
+ * @param sample_time clock number I2C used to sample data on SDA after the rising-edge of SCL, it's a 10-bit value
+ * @param hold_time clock number I2C used to hold the data after the falling-edge of SCL, it's a 10-bit value
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t i2c_set_data_timing(i2c_port_t i2c_num, int sample_time, int hold_time);
+
+/**
+ * @brief get I2C data signal timing
+ *
+ * @param i2c_num I2C port number
+ * @param sample_time pointer to get sample time
+ * @param hold_time pointer to get hold time
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t i2c_get_data_timing(i2c_port_t i2c_num, int* sample_time, int* hold_time);
+
+/**
+ * @brief set I2C timeout value
+ * @param i2c_num I2C port number
+ * @param timeout timeout value for I2C bus (unit: APB 80Mhz clock cycle)
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t i2c_set_timeout(i2c_port_t i2c_num, int timeout);
+
+/**
+ * @brief get I2C timeout value
+ * @param i2c_num I2C port number
+ * @param timeout pointer to get timeout value
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t i2c_get_timeout(i2c_port_t i2c_num, int* timeout);
+/**
+ * @brief set I2C data transfer mode
+ *
+ * @param i2c_num I2C port number
+ * @param tx_trans_mode I2C sending data mode
+ * @param rx_trans_mode I2C receving data mode
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t i2c_set_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t tx_trans_mode, i2c_trans_mode_t rx_trans_mode);
+
+/**
+ * @brief get I2C data transfer mode
+ *
+ * @param i2c_num I2C port number
+ * @param tx_trans_mode pointer to get I2C sending data mode
+ * @param rx_trans_mode pointer to get I2C receiving data mode
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t i2c_get_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t *tx_trans_mode, i2c_trans_mode_t *rx_trans_mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_DRIVER_I2C_H_*/
diff --git a/components/driver/include/driver/ledc.h b/components/driver/include/driver/ledc.h
index 8f70b1c003..6a82c19a2f 100644
--- a/components/driver/include/driver/ledc.h
+++ b/components/driver/include/driver/ledc.h
@@ -455,7 +455,7 @@ void ledc_fade_func_uninstall();
esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_fade_mode_t fade_mode);
/**
- * @brief A thread-safe API to set duty for LEDC channel and update the settings immediately
+ * @brief A thread-safe API to set duty for LEDC channel and return when duty updated.
* @note If a fade operation is running in progress on that channel, the driver would not allow it to be stopped.
* Other duty operations will have to wait until the fade operation has finished.
*
diff --git a/components/driver/include/driver/mcpwm.h b/components/driver/include/driver/mcpwm.h
index 2a4433fce4..d1c10e8672 100644
--- a/components/driver/include/driver/mcpwm.h
+++ b/components/driver/include/driver/mcpwm.h
@@ -1,709 +1,709 @@
-// Copyright 2015-2016 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.
-
-#ifndef _DRIVER_MCPWM_H_
-#define _DRIVER_MCPWM_H_
-
-#include "esp_err.h"
-#include "soc/soc.h"
-#include "driver/gpio.h"
-#include "driver/periph_ctrl.h"
-#include "esp_intr.h"
-#include "esp_intr_alloc.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief IO signals for MCPWM
- * 6 MCPWM output pins that generate PWM signals
- * 3 MCPWM fault input pins to detect faults like overcurrent, overvoltage, etc
- * 3 MCPWM sync input pins to synchronize MCPWM outputs signals
- * 3 MCPWM capture input pin to capture hall sell signal to measure time
- */
-typedef enum {
- MCPWM0A = 0, /*!
#include
#include "esp_err.h"
-#include "soc/spi_struct.h"
#include "rom/lldesc.h"
-
+#include "soc/spi_periph.h"
+#include "sdkconfig.h"
#ifdef __cplusplus
extern "C"
@@ -32,6 +32,34 @@ extern "C"
//Maximum amount of bytes that can be put in one DMA descriptor
#define SPI_MAX_DMA_LEN (4096-4)
+/**
+ * Transform unsigned integer of length <= 32 bits to the format which can be
+ * sent by the SPI driver directly.
+ *
+ * E.g. to send 9 bits of data, you can:
+ *
+ * uint16_t data = SPI_SWAP_DATA_TX(0x145, 9);
+ *
+ * Then points tx_buffer to ``&data``.
+ *
+ * @param data Data to be sent, can be uint8_t, uint16_t or uint32_t. @param
+ * len Length of data to be sent, since the SPI peripheral sends from the MSB,
+ * this helps to shift the data to the MSB.
+ */
+#define SPI_SWAP_DATA_TX(data, len) __builtin_bswap32((uint32_t)data<<(32-len))
+
+/**
+ * Transform received data of length <= 32 bits to the format of an unsigned integer.
+ *
+ * E.g. to transform the data of 15 bits placed in a 4-byte array to integer:
+ *
+ * uint16_t data = SPI_SWAP_DATA_RX(*(uint32_t*)t->rx_data, 15);
+ *
+ * @param data Data to be rearranged, can be uint8_t, uint16_t or uint32_t.
+ * @param len Length of data received, since the SPI peripheral writes from
+ * the MSB, this helps to shift the data to the LSB.
+ */
+#define SPI_SWAP_DATA_RX(data, len) (__builtin_bswap32(data)>>(32-len))
/**
* @brief Enum with the three SPI peripherals that are software-accessible in it
@@ -46,7 +74,7 @@ typedef enum {
* @brief This is a configuration structure for a SPI bus.
*
* You can use this structure to specify the GPIO pins of the bus. Normally, the driver will use the
- * GPIO matrix to route the signals. An exception is made when all signals either can be routed through
+ * GPIO matrix to route the signals. An exception is made when all signals either can be routed through
* the IO_MUX or are -1. In that case, the IO_MUX is used, allowing for >40MHz speeds.
*
* @note Be advised that the slave driver does not use the quadwp/quadhd lines and fields in spi_bus_config_t refering to these lines will be ignored and can thus safely be left uninitialized.
@@ -82,29 +110,27 @@ bool spicommon_periph_free(spi_host_device_t host);
/**
* @brief Try to claim a SPI DMA channel
- *
+ *
* Call this if your driver wants to use SPI with a DMA channnel.
- *
+ *
* @param dma_chan channel to claim
- *
+ *
* @return True if success; false otherwise.
*/
bool spicommon_dma_chan_claim(int dma_chan);
/**
* @brief Return the SPI DMA channel so other driver can claim it, or just to power down DMA.
- *
+ *
* @param dma_chan channel to return
- *
+ *
* @return True if success; false otherwise.
*/
bool spicommon_dma_chan_free(int dma_chan);
-
-
#define SPICOMMON_BUSFLAG_SLAVE 0 ///< Initialize I/O in slave mode
#define SPICOMMON_BUSFLAG_MASTER (1<<0) ///< Initialize I/O in master mode
-#define SPICOMMON_BUSFLAG_NATIVE_PINS (1<<1) ///< Check using native pins. Or indicates the pins are configured through the IO mux rather than GPIO matrix.
+#define SPICOMMON_BUSFLAG_NATIVE_PINS (1<<1) ///< Check using iomux pins. Or indicates the pins are configured through the IO mux rather than GPIO matrix.
#define SPICOMMON_BUSFLAG_SCLK (1<<2) ///< Check existing of SCLK pin. Or indicates CLK line initialized.
#define SPICOMMON_BUSFLAG_MISO (1<<3) ///< Check existing of MISO pin. Or indicates MISO line initialized.
#define SPICOMMON_BUSFLAG_MOSI (1<<4) ///< Check existing of MOSI pin. Or indicates CLK line initialized.
@@ -116,7 +142,7 @@ bool spicommon_dma_chan_free(int dma_chan);
* @brief Connect a SPI peripheral to GPIO pins
*
* This routine is used to connect a SPI peripheral to the IO-pads and DMA channel given in
- * the arguments. Depending on the IO-pads requested, the routing is done either using the
+ * the arguments. Depending on the IO-pads requested, the routing is done either using the
* IO_mux or using the GPIO matrix.
*
* @param host SPI peripheral to be routed
@@ -125,21 +151,21 @@ bool spicommon_dma_chan_free(int dma_chan);
* @param flags Combination of SPICOMMON_BUSFLAG_* flags, set to ensure the pins set are capable with some functions:
* - ``SPICOMMON_BUSFLAG_MASTER``: Initialize I/O in master mode
* - ``SPICOMMON_BUSFLAG_SLAVE``: Initialize I/O in slave mode
- * - ``SPICOMMON_BUSFLAG_NATIVE_PINS``: Pins set should match the native pins of the controller.
- * - ``SPICOMMON_BUSFLAG_SCLK``, ``SPICOMMON_BUSFLAG_MISO``, ``SPICOMMON_BUSFLAG_MOSI``:
+ * - ``SPICOMMON_BUSFLAG_NATIVE_PINS``: Pins set should match the iomux pins of the controller.
+ * - ``SPICOMMON_BUSFLAG_SCLK``, ``SPICOMMON_BUSFLAG_MISO``, ``SPICOMMON_BUSFLAG_MOSI``:
* Make sure SCLK/MISO/MOSI is/are set to a valid GPIO. Also check output capability according to the mode.
* - ``SPICOMMON_BUSFLAG_DUAL``: Make sure both MISO and MOSI are output capable so that DIO mode is capable.
* - ``SPICOMMON_BUSFLAG_WPHD`` Make sure WP and HD are set to valid output GPIOs.
* - ``SPICOMMON_BUSFLAG_QUAD``: Combination of ``SPICOMMON_BUSFLAG_DUAL`` and ``SPICOMMON_BUSFLAG_WPHD``.
* @param[out] flags_o A SPICOMMON_BUSFLAG_* flag combination of bus abilities will be written to this address.
* Leave to NULL if not needed.
- * - ``SPICOMMON_BUSFLAG_NATIVE_PINS``: The bus is connected to native pins.
+ * - ``SPICOMMON_BUSFLAG_NATIVE_PINS``: The bus is connected to iomux pins.
* - ``SPICOMMON_BUSFLAG_SCLK``, ``SPICOMMON_BUSFLAG_MISO``, ``SPICOMMON_BUSFLAG_MOSI``: The bus has
* CLK/MISO/MOSI connected.
* - ``SPICOMMON_BUSFLAG_DUAL``: The bus is capable with DIO mode.
* - ``SPICOMMON_BUSFLAG_WPHD`` The bus has WP and HD connected.
* - ``SPICOMMON_BUSFLAG_QUAD``: Combination of ``SPICOMMON_BUSFLAG_DUAL`` and ``SPICOMMON_BUSFLAG_WPHD``.
- * @return
+ * @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_OK on success
*/
@@ -147,14 +173,26 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
/**
* @brief Free the IO used by a SPI peripheral
+ * @deprecated Use spicommon_bus_free_io_cfg instead.
*
* @param host SPI peripheral to be freed
- * @return
+ *
+ * @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_OK on success
*/
+esp_err_t spicommon_bus_free_io(spi_host_device_t host) __attribute__((deprecated));
-esp_err_t spicommon_bus_free_io(spi_host_device_t host);
+/**
+ * @brief Free the IO used by a SPI peripheral
+ *
+ * @param bus_cfg Bus config struct which defines which pins to be used.
+ *
+ * @return
+ * - ESP_ERR_INVALID_ARG if parameter is invalid
+ * - ESP_OK on success
+ */
+esp_err_t spicommon_bus_free_io_cfg(const spi_bus_config_t *bus_cfg);
/**
* @brief Initialize a Chip Select pin for a specific SPI peripheral
@@ -171,12 +209,19 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num,
/**
* @brief Free a chip select line
+ * @deprecated Use spicommon_cs_io, which inputs the gpio num rather than the cs id instead.
*
* @param host SPI peripheral
* @param cs_num CS id to free
*/
-void spicommon_cs_free(spi_host_device_t host, int cs_num);
+void spicommon_cs_free(spi_host_device_t host, int cs_num) __attribute__((deprecated));
+/**
+ * @brief Free a chip select line
+ *
+ * @param cs_gpio_num CS gpio num to free
+ */
+void spicommon_cs_free_io(int cs_gpio_num);
/**
* @brief Setup a DMA link chain
@@ -224,10 +269,10 @@ typedef void(*dmaworkaround_cb_t)(void *arg);
* @note In some (well-defined) cases in the ESP32 (at least rev v.0 and v.1), a SPI DMA channel will get confused. This can be remedied
* by resetting the SPI DMA hardware in case this happens. Unfortunately, the reset knob used for thsi will reset _both_ DMA channels, and
* as such can only done safely when both DMA channels are idle. These functions coordinate this.
- *
+ *
* Essentially, when a reset is needed, a driver can request this using spicommon_dmaworkaround_req_reset. This is supposed to be called
- * with an user-supplied function as an argument. If both DMA channels are idle, this call will reset the DMA subsystem and return true.
- * If the other DMA channel is still busy, it will return false; as soon as the other DMA channel is done, however, it will reset the
+ * with an user-supplied function as an argument. If both DMA channels are idle, this call will reset the DMA subsystem and return true.
+ * If the other DMA channel is still busy, it will return false; as soon as the other DMA channel is done, however, it will reset the
* DMA subsystem and call the callback. The callback is then supposed to be used to continue the SPI drivers activity.
*
* @param dmachan DMA channel associated with the SPI host that needs a reset
diff --git a/components/driver/include/driver/spi_master.h b/components/driver/include/driver/spi_master.h
index 232ad36eb7..4e64c404ed 100644
--- a/components/driver/include/driver/spi_master.h
+++ b/components/driver/include/driver/spi_master.h
@@ -1,4 +1,4 @@
-// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD
+// Copyright 2010-2018 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.
@@ -22,6 +22,19 @@
#include "driver/spi_common.h"
+/** SPI master clock is divided by 80MHz apb clock. Below defines are example frequencies, and are accurate. Be free to specify a random frequency, it will be rounded to closest frequency (to macros below if above 8MHz).
+ * 8MHz
+ */
+#define SPI_MASTER_FREQ_8M (APB_CLK_FREQ/10)
+#define SPI_MASTER_FREQ_9M (APB_CLK_FREQ/9) ///< 8.89MHz
+#define SPI_MASTER_FREQ_10M (APB_CLK_FREQ/8) ///< 10MHz
+#define SPI_MASTER_FREQ_11M (APB_CLK_FREQ/7) ///< 11.43MHz
+#define SPI_MASTER_FREQ_13M (APB_CLK_FREQ/6) ///< 13.33MHz
+#define SPI_MASTER_FREQ_16M (APB_CLK_FREQ/5) ///< 16MHz
+#define SPI_MASTER_FREQ_20M (APB_CLK_FREQ/4) ///< 20MHz
+#define SPI_MASTER_FREQ_26M (APB_CLK_FREQ/3) ///< 26.67MHz
+#define SPI_MASTER_FREQ_40M (APB_CLK_FREQ/2) ///< 40MHz
+#define SPI_MASTER_FREQ_80M (APB_CLK_FREQ/1) ///< 80MHz
#ifdef __cplusplus
extern "C"
@@ -35,12 +48,12 @@ extern "C"
#define SPI_DEVICE_POSITIVE_CS (1<<3) ///< Make CS positive during a transaction instead of negative
#define SPI_DEVICE_HALFDUPLEX (1<<4) ///< Transmit data before receiving it, instead of simultaneously
#define SPI_DEVICE_CLK_AS_CS (1<<5) ///< Output clock on CS line if CS is active
-/** There are timing issue when reading at high frequency (the frequency is related to whether native pins are used, valid time after slave sees the clock).
+/** There are timing issue when reading at high frequency (the frequency is related to whether iomux pins are used, valid time after slave sees the clock).
* - In half-duplex mode, the driver automatically inserts dummy bits before reading phase to fix the timing issue. Set this flag to disable this feature.
* - In full-duplex mode, however, the hardware cannot use dummy bits, so there is no way to prevent data being read from getting corrupted.
* Set this flag to confirm that you're going to work with output only, or read without dummy bits at your own risk.
*/
-#define SPI_DEVICE_NO_DUMMY (1<<6)
+#define SPI_DEVICE_NO_DUMMY (1<<6)
typedef struct spi_transaction_t spi_transaction_t;
@@ -57,7 +70,12 @@ typedef struct {
uint8_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128.
uint8_t cs_ena_pretrans; ///< Amount of SPI bit-cycles the cs should be activated before the transmission (0-16). This only works on half-duplex transactions.
uint8_t cs_ena_posttrans; ///< Amount of SPI bit-cycles the cs should stay active after the transmission (0-16)
- int clock_speed_hz; ///< Clock speed, in Hz
+ int clock_speed_hz; ///< Clock speed, divisors of 80MHz, in Hz. See ``SPI_MASTER_FREQ_*``.
+ int input_delay_ns; /**< Maximum data valid time of slave. The time required between SCLK and MISO
+ valid, including the possible clock delay from slave to master. The driver uses this value to give an extra
+ delay before the MISO is ready on the line. Leave at 0 unless you know you need a delay. For better timing
+ performance at high frequency (over 8MHz), it's suggest to have the right value.
+ */
int spics_io_num; ///< CS GPIO pin for this device, or -1 if not used
uint32_t flags; ///< Bitwise OR of SPI_DEVICE_* flags
int queue_size; ///< Transaction queue size. This sets how many transactions can be 'in the air' (queued using spi_device_queue_trans but not yet finished using spi_device_get_trans_result) at the same time
@@ -87,9 +105,9 @@ struct spi_transaction_t {
*/
uint64_t addr; /**< Address data, of which the length is set in the ``address_bits`` of spi_device_interface_config_t.
*
- * NOTE: this field, used to be "address" in ESP-IDF 2.1 and before, is re-written to be used in a new way in ESP-IDF3.0.
+ * NOTE: this field, used to be "address" in ESP-IDF 2.1 and before, is re-written to be used in a new way in ESP-IDF3.0.
*
- * Example: write 0x123400 and address_bits=24 to send address of 0x12, 0x34, 0x00 (in previous version, you may have to write 0x12340000).
+ * Example: write 0x123400 and address_bits=24 to send address of 0x12, 0x34, 0x00 (in previous version, you may have to write 0x12340000).
*/
size_t length; ///< Total data length, in bits
size_t rxlength; ///< Total data length received, should be not greater than ``length`` in full-duplex mode (0 defaults this to the value of ``length``).
@@ -125,14 +143,14 @@ typedef struct spi_device_t* spi_device_handle_t; ///< Handle for a device on a
* @param host SPI peripheral that controls this bus
* @param bus_config Pointer to a spi_bus_config_t struct specifying how the host should be initialized
* @param dma_chan Either channel 1 or 2, or 0 in the case when no DMA is required. Selecting a DMA channel
- * for a SPI bus allows transfers on the bus to have sizes only limited by the amount of
+ * for a SPI bus allows transfers on the bus to have sizes only limited by the amount of
* internal memory. Selecting no DMA channel (by passing the value 0) limits the amount of
* bytes transfered to a maximum of 32.
*
- * @warning If a DMA channel is selected, any transmit and receive buffer used should be allocated in
+ * @warning If a DMA channel is selected, any transmit and receive buffer used should be allocated in
* DMA-capable memory.
*
- * @return
+ * @return
* - ESP_ERR_INVALID_ARG if configuration is invalid
* - ESP_ERR_INVALID_STATE if host already is in use
* - ESP_ERR_NO_MEM if out of memory
@@ -146,7 +164,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
* @warning In order for this to succeed, all devices have to be removed first.
*
* @param host SPI peripheral to free
- * @return
+ * @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_ERR_INVALID_STATE if not all devices on the bus are freed
* - ESP_OK on success
@@ -166,12 +184,12 @@ esp_err_t spi_bus_free(spi_host_device_t host);
* @param host SPI peripheral to allocate device on
* @param dev_config SPI interface protocol config for the device
* @param handle Pointer to variable to hold the device handle
- * @return
+ * @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_ERR_NOT_FOUND if host doesn't have any free CS slots
* - ESP_ERR_NO_MEM if out of memory
* - ESP_OK on success
- */
+ */
esp_err_t spi_bus_add_device(spi_host_device_t host, const spi_device_interface_config_t *dev_config, spi_device_handle_t *handle);
@@ -179,7 +197,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host, const spi_device_interface_
* @brief Remove a device from the SPI bus
*
* @param handle Device handle to free
- * @return
+ * @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_ERR_INVALID_STATE if device already is freed
* - ESP_OK on success
@@ -206,18 +224,18 @@ esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *
/**
* @brief Get the result of a SPI transaction queued earlier
*
- * This routine will wait until a transaction to the given device (queued earlier with
+ * This routine will wait until a transaction to the given device (queued earlier with
* spi_device_queue_trans) has succesfully completed. It will then return the description of the
- * completed transaction so software can inspect the result and e.g. free the memory or
+ * completed transaction so software can inspect the result and e.g. free the memory or
* re-use the buffers.
*
* @param handle Device handle obtained using spi_host_add_dev
- * @param trans_desc Pointer to variable able to contain a pointer to the description of the transaction
- that is executed. The descriptor should not be modified until the descriptor is returned by
+ * @param trans_desc Pointer to variable able to contain a pointer to the description of the transaction
+ that is executed. The descriptor should not be modified until the descriptor is returned by
spi_device_get_trans_result.
* @param ticks_to_wait Ticks to wait until there's a returned item; use portMAX_DELAY to never time
out.
- * @return
+ * @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_ERR_TIMEOUT if there was no completed transaction before ticks_to_wait expired
* - ESP_OK on success
@@ -253,6 +271,30 @@ esp_err_t spi_device_transmit(spi_device_handle_t handle, spi_transaction_t *tra
*/
int spi_cal_clock(int fapb, int hz, int duty_cycle, uint32_t* reg_o);
+/**
+ * @brief Calculate the timing settings of specified frequency and settings.
+ *
+ * @param gpio_is_used True if using GPIO matrix, or False if iomux pins are used.
+ * @param input_delay_ns Input delay from SCLK launch edge to MISO data valid.
+ * @param eff_clk Effective clock frequency (in Hz) from spi_cal_clock.
+ * @param dummy_o Address of dummy bits used output. Set to NULL if not needed.
+ * @param cycles_remain_o Address of cycles remaining (after dummy bits are used) output.
+ * - -1 If too many cycles remaining, suggest to compensate half a clock.
+ * - 0 If no remaining cycles or dummy bits are not used.
+ * - positive value: cycles suggest to compensate.
+ * @note If **dummy_o* is not zero, it means dummy bits should be applied in half duplex mode, and full duplex mode may not work.
+ */
+void spi_get_timing(bool gpio_is_used, int input_delay_ns, int eff_clk, int* dummy_o, int* cycles_remain_o);
+
+/**
+ * @brief Get the frequency limit of current configurations.
+ * SPI master working at this limit is OK, while above the limit, full duplex mode and DMA will not work,
+ * and dummy bits will be aplied in the half duplex mode.
+ * @param gpio_is_used True if using GPIO matrix, or False if native pins are used.
+ * @param input_delay_ns Input delay from SCLK launch edge to MISO data valid.
+ * @return Frequency limit of current configurations.
+ */
+int spi_get_freq_limit(bool gpio_is_used, int input_delay_ns);
#ifdef __cplusplus
}
diff --git a/components/driver/include/driver/spi_slave.h b/components/driver/include/driver/spi_slave.h
index 1d5ea34029..9ad4b9126d 100644
--- a/components/driver/include/driver/spi_slave.h
+++ b/components/driver/include/driver/spi_slave.h
@@ -1,4 +1,4 @@
-// Copyright 2010-2017 Espressif Systems (Shanghai) PTE LTD
+// Copyright 2010-2018 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.
diff --git a/components/driver/include/driver/touch_pad.h b/components/driver/include/driver/touch_pad.h
index f18069ab3c..21e2e2ec7c 100644
--- a/components/driver/include/driver/touch_pad.h
+++ b/components/driver/include/driver/touch_pad.h
@@ -122,6 +122,7 @@ esp_err_t touch_pad_init();
/**
* @brief Un-install touch pad driver.
+ * @note After this function is called, other touch functions are prohibited from being called.
* @return
* - ESP_OK Success
* - ESP_FAIL Touch pad driver not initialized
@@ -130,8 +131,12 @@ esp_err_t touch_pad_deinit();
/**
* @brief Configure touch pad interrupt threshold.
+ *
+ * @note If FSM mode is set to TOUCH_FSM_MODE_TIMER, this function will be blocked for one measurement cycle and wait for data to be valid.
+ *
* @param touch_num touch pad index
* @param threshold interrupt threshold,
+ *
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG if argument wrong
@@ -144,28 +149,34 @@ esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold);
* Each touch sensor has a counter to count the number of charge/discharge cycles.
* When the pad is not 'touched', we can get a number of the counter.
* When the pad is 'touched', the value in counter will get smaller because of the larger equivalent capacitance.
- * @note This API requests hardware measurement once. If IIR filter mode is enabled,,
+ *
+ * @note This API requests hardware measurement once. If IIR filter mode is enabled,
* please use 'touch_pad_read_raw_data' interface instead.
+ *
* @param touch_num touch pad index
* @param touch_value pointer to accept touch sensor value
+ *
* @return
* - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Touch pad error
+ * - ESP_ERR_INVALID_ARG Touch pad parameter error
+ * - ESP_ERR_INVALID_STATE This touch pad hardware connection is error, the value of "touch_value" is 0.
* - ESP_FAIL Touch pad not initialized
*/
esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t * touch_value);
/**
* @brief get filtered touch sensor counter value by IIR filter.
+ *
* @note touch_pad_filter_start has to be called before calling touch_pad_read_filtered.
* This function can be called from ISR
*
* @param touch_num touch pad index
* @param touch_value pointer to accept touch sensor value
+ *
* @return
* - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Touch pad error
- * - ESP_ERR_INVALID_STATE Touch pad not initialized
+ * - ESP_ERR_INVALID_ARG Touch pad parameter error
+ * - ESP_ERR_INVALID_STATE This touch pad hardware connection is error, the value of "touch_value" is 0.
* - ESP_FAIL Touch pad not initialized
*/
esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *touch_value);
@@ -173,6 +184,7 @@ esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *touch_value);
/**
* @brief get raw data (touch sensor counter value) from IIR filter process.
* Need not request hardware measurements.
+ *
* @note touch_pad_filter_start has to be called before calling touch_pad_read_raw_data.
* This function can be called from ISR
*
@@ -180,10 +192,10 @@ esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *touch_value);
* @param touch_value pointer to accept touch sensor value
*
* @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Touch pad error
- * - ESP_ERR_INVALID_STATE Touch pad not initialized
- * - ESP_FAIL Touch pad not initialized
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Touch pad parameter error
+ * - ESP_ERR_INVALID_STATE This touch pad hardware connection is error, the value of "touch_value" is 0.
+ * - ESP_FAIL Touch pad not initialized
*/
esp_err_t touch_pad_read_raw_data(touch_pad_t touch_num, uint16_t *touch_value);
@@ -508,8 +520,6 @@ esp_err_t touch_pad_get_filter_period(uint32_t* p_period_ms);
* when detecting slight change of capacitance.
* Need to call touch_pad_filter_start before all touch filter APIs
*
- * If filter is not initialized, this API will initialize the filter with given period.
- * If filter is already initialized, this API will update the filter period.
* @note This filter uses FreeRTOS timer, which is dispatched from a task with
* priority 1 by default on CPU 0. So if some application task with higher priority
* takes a lot of CPU0 time, then the quality of data obtained from this filter will be affected.
@@ -541,6 +551,15 @@ esp_err_t touch_pad_filter_stop();
*/
esp_err_t touch_pad_filter_delete();
+/**
+ * @brief Get the touch pad which caused wakeup from sleep
+ * @param pad_num pointer to touch pad which caused wakeup
+ * @return
+ * - ESP_OK Success
+ * - ESP_FAIL get status err
+ */
+esp_err_t touch_pad_get_wakeup_status(touch_pad_t *pad_num);
+
#ifdef __cplusplus
}
#endif
diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h
index 08c398f61f..ed85e18a11 100644
--- a/components/driver/include/driver/uart.h
+++ b/components/driver/include/driver/uart.h
@@ -46,6 +46,17 @@ extern "C" {
#define UART_INVERSE_TXD (UART_TXD_INV_M) /*!< UART TXD output inverse*/
#define UART_INVERSE_RTS (UART_RTS_INV_M) /*!< UART RTS output inverse*/
+/**
+ * @brief UART mode selection
+ */
+typedef enum {
+ UART_MODE_UART = 0x00, /*!< mode: regular UART mode*/
+ UART_MODE_RS485_HALF_DUPLEX = 0x01, /*!< mode: half duplex RS485 UART mode control by RTS pin */
+ UART_MODE_IRDA = 0x02, /*!< mode: IRDA UART mode*/
+ UART_MODE_RS485_COLLISION_DETECT = 0x03, /*!< mode: RS485 collision detection UART mode (used for test purposes)*/
+ UART_MODE_RS485_APP_CTRL = 0x04, /*!< mode: application control RS485 UART mode (used for test purposes)*/
+} uart_mode_t;
+
/**
* @brief UART word length constants
*/
@@ -54,7 +65,7 @@ typedef enum {
UART_DATA_6_BITS = 0x1, /*!< word length: 6bits*/
UART_DATA_7_BITS = 0x2, /*!< word length: 7bits*/
UART_DATA_8_BITS = 0x3, /*!< word length: 8bits*/
- UART_DATA_BITS_MAX = 0X4,
+ UART_DATA_BITS_MAX = 0x4,
} uart_word_length_t;
/**
@@ -249,8 +260,8 @@ esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate);
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param inverse_mask Choose the wires that need to be inverted.
* Inverse_mask should be chosen from
- UART_INVERSE_RXD / UART_INVERSE_TXD / UART_INVERSE_RTS / UART_INVERSE_CTS,
- combined with OR operation.
+ * UART_INVERSE_RXD / UART_INVERSE_TXD / UART_INVERSE_RTS / UART_INVERSE_CTS,
+ * combined with OR operation.
*
* @return
* - ESP_OK Success
@@ -474,7 +485,7 @@ esp_err_t uart_set_dtr(uart_port_t uart_num, int level);
esp_err_t uart_set_tx_idle_num(uart_port_t uart_num, uint16_t idle_num);
/**
-* @brief Set UART configuration parameters.
+ * @brief Set UART configuration parameters.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param uart_config UART parameter settings
@@ -486,7 +497,7 @@ esp_err_t uart_set_tx_idle_num(uart_port_t uart_num, uint16_t idle_num);
esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config);
/**
-* @brief Configure UART interrupts.
+ * @brief Configure UART interrupts.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param intr_conf UART interrupt settings
@@ -552,8 +563,8 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait);
* @note This function should only be used when UART TX buffer is not enabled.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
- * @param buffer data buffer address
- * @param len data length to send
+ * @param buffer data buffer address
+ * @param len data length to send
*
* @return
* - (-1) Parameter error
@@ -571,8 +582,8 @@ int uart_tx_chars(uart_port_t uart_num, const char* buffer, uint32_t len);
* UART ISR will then move data from the ring buffer to TX FIFO gradually.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
- * @param src data buffer address
- * @param size data length to send
+ * @param src data buffer address
+ * @param size data length to send
*
* @return
* - (-1) Parameter error
@@ -581,7 +592,7 @@ int uart_tx_chars(uart_port_t uart_num, const char* buffer, uint32_t len);
int uart_write_bytes(uart_port_t uart_num, const char* src, size_t size);
/**
- * @brief Send data to the UART port from a given buffer and length.
+ * @brief Send data to the UART port from a given buffer and length,
*
* If the UART driver's parameter 'tx_buffer_size' is set to zero:
* This function will not return until all the data and the break signal have been sent out.
@@ -641,9 +652,10 @@ esp_err_t uart_flush(uart_port_t uart_num);
esp_err_t uart_flush_input(uart_port_t uart_num);
/**
- * @brief UART get RX ring buffer cached data length
- * @param uart_num UART port number.
- * @param size Pointer of size_t to accept cached data length
+ * @brief UART get RX ring buffer cached data length
+ *
+ * @param uart_num UART port number.
+ * @param size Pointer of size_t to accept cached data length
*
* @return
* - ESP_OK Success
@@ -652,9 +664,9 @@ esp_err_t uart_flush_input(uart_port_t uart_num);
esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t* size);
/**
- * @brief UART disable pattern detect function.
- * Designed for applications like 'AT commands'.
- * When the hardware detects a series of one same character, the interrupt will be triggered.
+ * @brief UART disable pattern detect function.
+ * Designed for applications like 'AT commands'.
+ * When the hardware detects a series of one same character, the interrupt will be triggered.
*
* @param uart_num UART port number.
*
@@ -737,6 +749,49 @@ int uart_pattern_get_pos(uart_port_t uart_num);
*/
esp_err_t uart_pattern_queue_reset(uart_port_t uart_num, int queue_length);
+/**
+ * @brief UART set communication mode
+ * @note This function must be executed after uart_driver_install(), when the driver object is initialized.
+ * @param uart_num Uart number to configure
+ * @param mode UART UART mode to set
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode);
+
+/**
+ * @brief UART set threshold timeout for TOUT feature
+ *
+ * @param uart_num Uart number to configure
+ * @param tout_thresh This parameter defines timeout threshold in uart symbol periods. The maximum value of threshold is 126.
+ * tout_thresh = 1, defines TOUT interrupt timeout equal to transmission time of one symbol (~11 bit) on current baudrate.
+ * If the time is expired the UART_RXFIFO_TOUT_INT interrupt is triggered. If tout_thresh == 0,
+ * the TOUT feature is disabled.
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ * - ESP_ERR_INVALID_STATE Driver is not installed
+ */
+esp_err_t uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh);
+
+/**
+ * @brief Returns collision detection flag for RS485 mode
+ * Function returns the collision detection flag into variable pointed by collision_flag.
+ * *collision_flag = true, if collision detected else it is equal to false.
+ * This function should be executed when actual transmission is completed (after uart_write_bytes()).
+ *
+ * @param uart_num Uart number to configure
+ * @param collision_flag Pointer to variable of type bool to return collision flag.
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t uart_get_collision_flag(uart_port_t uart_num, bool* collision_flag);
+
#ifdef __cplusplus
}
#endif
diff --git a/components/driver/ledc.c b/components/driver/ledc.c
index 6891877c86..c2cb94e591 100644
--- a/components/driver/ledc.c
+++ b/components/driver/ledc.c
@@ -449,6 +449,7 @@ esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t
ret = ESP_FAIL;
}
LEDC.timer_group[speed_mode].timer[timer_num].conf.clock_divider = clock_divider;
+ ledc_ls_timer_update(speed_mode, timer_num);
portEXIT_CRITICAL(&ledc_spinlock);
return ret;
}
@@ -587,7 +588,7 @@ static esp_err_t _ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t
{
portENTER_CRITICAL(&ledc_spinlock);
uint32_t duty_cur = LEDC.channel_group[speed_mode].channel[channel].duty_rd.duty_read >> LEDC_DUTY_DECIMAL_BIT_NUM;
- // if duty == max_duty and scale and fade_down == 1, counter would overflow.
+ // When duty == max_duty, meanwhile, if scale == 1 and fade_down == 1, counter would overflow.
if (duty_cur == ledc_get_max_duty(speed_mode, channel)) {
duty_cur -= 1;
}
@@ -609,6 +610,7 @@ static esp_err_t _ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t
step_num = step_num > LEDC_STEP_NUM_MAX ? LEDC_STEP_NUM_MAX : step_num;
}
}
+
portEXIT_CRITICAL(&ledc_spinlock);
if (scale > 0 && step_num > 0) {
ledc_duty_config(speed_mode, channel, LEDC_VAL_NO_CHANGE, duty_cur << 4, dir, step_num, cycle_num, scale);
@@ -736,18 +738,16 @@ esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channe
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
LEDC_ARG_CHECK(duty <= ledc_get_max_duty(speed_mode, channel), "target_duty");
+ LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK , LEDC_FADE_INIT_ERROR_STR, ESP_FAIL);
+ uint32_t cur_duty = ledc_get_duty(speed_mode, channel);
+ if (duty == cur_duty) {
+ return ESP_OK;
+ }
_ledc_op_lock_acquire(speed_mode, channel);
_ledc_fade_hw_acquire(speed_mode, channel);
- ledc_duty_config(speed_mode,
- channel, //uint32_t chan_num,
- hpoint, //uint32_t hpoint_val,
- duty << 4, //uint32_t duty_val,the least 4 bits are decimal part
- 1, //uint32_t increase,
- 1, //uint32_t duty_num,
- 1, //uint32_t duty_cycle,
- 0 //uint32_t duty_scale
- );
- ledc_update_duty(speed_mode, channel);
+ int scale = cur_duty > duty ? cur_duty - duty : duty - cur_duty;
+ _ledc_set_fade_with_step(speed_mode, channel, duty, scale, 1);
+ _ledc_fade_start(speed_mode, channel, LEDC_FADE_WAIT_DONE);
_ledc_fade_hw_release(speed_mode, channel);
_ledc_op_lock_release(speed_mode, channel);
return ESP_OK;
diff --git a/components/driver/pcnt.c b/components/driver/pcnt.c
index b859b495b1..6fcc2b5525 100644
--- a/components/driver/pcnt.c
+++ b/components/driver/pcnt.c
@@ -24,6 +24,7 @@
#define PCNT_COUNT_MODE_ERR_STR "PCNT COUNTER MODE ERROR"
#define PCNT_CTRL_MODE_ERR_STR "PCNT CTRL MODE ERROR"
#define PCNT_EVT_TYPE_ERR_STR "PCNT value type error"
+#define PCNT_LIMT_VAL_ERR_STR "PCNT limit value error"
#define PCNT_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux)
#define PCNT_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux)
@@ -221,6 +222,8 @@ esp_err_t pcnt_set_event_value(pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16
{
PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
PCNT_CHECK(evt_type < PCNT_EVT_MAX, PCNT_EVT_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
+ PCNT_CHECK(!(evt_type == PCNT_EVT_L_LIM && value > 0), PCNT_LIMT_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
+ PCNT_CHECK(!(evt_type == PCNT_EVT_H_LIM && value < 0), PCNT_LIMT_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
if(evt_type == PCNT_EVT_L_LIM) {
PCNT.conf_unit[unit].conf2.cnt_l_lim = value;
} else if(evt_type == PCNT_EVT_H_LIM) {
diff --git a/components/driver/rmt.c b/components/driver/rmt.c
index 9460cefa71..8ee1640c0b 100644
--- a/components/driver/rmt.c
+++ b/components/driver/rmt.c
@@ -137,7 +137,7 @@ esp_err_t rmt_get_rx_idle_thresh(rmt_channel_t channel, uint16_t *thresh)
esp_err_t rmt_set_mem_block_num(rmt_channel_t channel, uint8_t rmt_mem_num)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
- RMT_CHECK(rmt_mem_num < 16, RMT_MEM_CNT_ERROR_STR, ESP_ERR_INVALID_ARG);
+ RMT_CHECK(rmt_mem_num <= RMT_CHANNEL_MAX - channel, RMT_MEM_CNT_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT.conf_ch[channel].conf0.mem_size = rmt_mem_num;
return ESP_OK;
}
@@ -669,7 +669,7 @@ esp_err_t rmt_driver_uninstall(rmt_channel_t channel)
}
//Avoid blocking here(when the interrupt is disabled and do not wait tx done).
if(p_rmt_obj[channel]->wait_done) {
- xSemaphoreTake(p_rmt_obj[channel]->tx_sem, portMAX_DELAY);
+ xSemaphoreTake(p_rmt_obj[channel]->tx_sem, portMAX_DELAY);
}
rmt_set_rx_intr_en(channel, 0);
rmt_set_err_intr_en(channel, 0);
@@ -929,4 +929,4 @@ esp_err_t rmt_write_sample(rmt_channel_t channel, const uint8_t *src, size_t src
xSemaphoreGive(p_rmt->tx_sem);
}
return ESP_OK;
-}
\ No newline at end of file
+}
diff --git a/components/driver/rtc_module.c b/components/driver/rtc_module.c
index d08cbd1357..f7f63100af 100644
--- a/components/driver/rtc_module.c
+++ b/components/driver/rtc_module.c
@@ -1,6 +1,9 @@
+// Copyright 2016-2018 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
@@ -22,6 +25,7 @@
#include "soc/rtc_cntl_struct.h"
#include "soc/syscon_reg.h"
#include "soc/syscon_struct.h"
+#include "soc/rtc.h"
#include "rtc_io.h"
#include "touch_pad.h"
#include "adc.h"
@@ -97,12 +101,12 @@ In ADC2, there're two locks used for different cases:
adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock.
*/
//prevent ADC2 being used by wifi and other tasks at the same time.
-static _lock_t adc2_wifi_lock = NULL;
+static _lock_t adc2_wifi_lock;
//prevent ADC2 being used by tasks (regardless of WIFI)
portMUX_TYPE adc2_spinlock = portMUX_INITIALIZER_UNLOCKED;
//prevent ADC1 being used by I2S dma and other tasks at the same time.
-static _lock_t adc1_i2s_lock = NULL;
+static _lock_t adc1_i2s_lock;
typedef struct {
TimerHandle_t timer;
@@ -117,50 +121,6 @@ static touch_pad_filter_t *s_touch_pad_filter = NULL;
static uint16_t s_touch_pad_init_bit = 0x0000;
static filter_cb_t s_filter_cb = NULL;
-//Reg,Mux,Fun,IE,Up,Down,Rtc_number
-const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT] = {
- {RTC_IO_TOUCH_PAD1_REG, RTC_IO_TOUCH_PAD1_MUX_SEL_M, RTC_IO_TOUCH_PAD1_FUN_SEL_S, RTC_IO_TOUCH_PAD1_FUN_IE_M, RTC_IO_TOUCH_PAD1_RUE_M, RTC_IO_TOUCH_PAD1_RDE_M, RTC_IO_TOUCH_PAD1_SLP_SEL_M, RTC_IO_TOUCH_PAD1_SLP_IE_M, RTC_IO_TOUCH_PAD1_HOLD_M, RTC_CNTL_TOUCH_PAD1_HOLD_FORCE_M, RTC_IO_TOUCH_PAD1_DRV_V, RTC_IO_TOUCH_PAD1_DRV_S, RTCIO_GPIO0_CHANNEL}, //0
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //1
- {RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_MUX_SEL_M, RTC_IO_TOUCH_PAD2_FUN_SEL_S, RTC_IO_TOUCH_PAD2_FUN_IE_M, RTC_IO_TOUCH_PAD2_RUE_M, RTC_IO_TOUCH_PAD2_RDE_M, RTC_IO_TOUCH_PAD2_SLP_SEL_M, RTC_IO_TOUCH_PAD2_SLP_IE_M, RTC_IO_TOUCH_PAD2_HOLD_M, RTC_CNTL_TOUCH_PAD2_HOLD_FORCE_M, RTC_IO_TOUCH_PAD2_DRV_V, RTC_IO_TOUCH_PAD2_DRV_S, RTCIO_GPIO2_CHANNEL}, //2
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //3
- {RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_MUX_SEL_M, RTC_IO_TOUCH_PAD0_FUN_SEL_S, RTC_IO_TOUCH_PAD0_FUN_IE_M, RTC_IO_TOUCH_PAD0_RUE_M, RTC_IO_TOUCH_PAD0_RDE_M, RTC_IO_TOUCH_PAD0_SLP_SEL_M, RTC_IO_TOUCH_PAD0_SLP_IE_M, RTC_IO_TOUCH_PAD0_HOLD_M, RTC_CNTL_TOUCH_PAD0_HOLD_FORCE_M, RTC_IO_TOUCH_PAD0_DRV_V, RTC_IO_TOUCH_PAD0_DRV_S, RTCIO_GPIO4_CHANNEL}, //4
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //5
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //6
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //7
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //8
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //9
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //10
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //11
- {RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_MUX_SEL_M, RTC_IO_TOUCH_PAD5_FUN_SEL_S, RTC_IO_TOUCH_PAD5_FUN_IE_M, RTC_IO_TOUCH_PAD5_RUE_M, RTC_IO_TOUCH_PAD5_RDE_M, RTC_IO_TOUCH_PAD5_SLP_SEL_M, RTC_IO_TOUCH_PAD5_SLP_IE_M, RTC_IO_TOUCH_PAD5_HOLD_M, RTC_CNTL_TOUCH_PAD5_HOLD_FORCE_M, RTC_IO_TOUCH_PAD5_DRV_V, RTC_IO_TOUCH_PAD5_DRV_S, RTCIO_GPIO12_CHANNEL}, //12
- {RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_MUX_SEL_M, RTC_IO_TOUCH_PAD4_FUN_SEL_S, RTC_IO_TOUCH_PAD4_FUN_IE_M, RTC_IO_TOUCH_PAD4_RUE_M, RTC_IO_TOUCH_PAD4_RDE_M, RTC_IO_TOUCH_PAD4_SLP_SEL_M, RTC_IO_TOUCH_PAD4_SLP_IE_M, RTC_IO_TOUCH_PAD4_HOLD_M, RTC_CNTL_TOUCH_PAD4_HOLD_FORCE_M, RTC_IO_TOUCH_PAD4_DRV_V, RTC_IO_TOUCH_PAD4_DRV_S, RTCIO_GPIO13_CHANNEL}, //13
- {RTC_IO_TOUCH_PAD6_REG, RTC_IO_TOUCH_PAD6_MUX_SEL_M, RTC_IO_TOUCH_PAD6_FUN_SEL_S, RTC_IO_TOUCH_PAD6_FUN_IE_M, RTC_IO_TOUCH_PAD6_RUE_M, RTC_IO_TOUCH_PAD6_RDE_M, RTC_IO_TOUCH_PAD6_SLP_SEL_M, RTC_IO_TOUCH_PAD6_SLP_IE_M, RTC_IO_TOUCH_PAD6_HOLD_M, RTC_CNTL_TOUCH_PAD6_HOLD_FORCE_M, RTC_IO_TOUCH_PAD6_DRV_V, RTC_IO_TOUCH_PAD6_DRV_S, RTCIO_GPIO14_CHANNEL}, //14
- {RTC_IO_TOUCH_PAD3_REG, RTC_IO_TOUCH_PAD3_MUX_SEL_M, RTC_IO_TOUCH_PAD3_FUN_SEL_S, RTC_IO_TOUCH_PAD3_FUN_IE_M, RTC_IO_TOUCH_PAD3_RUE_M, RTC_IO_TOUCH_PAD3_RDE_M, RTC_IO_TOUCH_PAD3_SLP_SEL_M, RTC_IO_TOUCH_PAD3_SLP_IE_M, RTC_IO_TOUCH_PAD3_HOLD_M, RTC_CNTL_TOUCH_PAD3_HOLD_FORCE_M, RTC_IO_TOUCH_PAD3_DRV_V, RTC_IO_TOUCH_PAD3_DRV_S, RTCIO_GPIO15_CHANNEL}, //15
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //16
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //17
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //18
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //19
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //20
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //21
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //22
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //23
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //24
- {RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_MUX_SEL_M, RTC_IO_PDAC1_FUN_SEL_S, RTC_IO_PDAC1_FUN_IE_M, RTC_IO_PDAC1_RUE_M, RTC_IO_PDAC1_RDE_M, RTC_IO_PDAC1_SLP_SEL_M, RTC_IO_PDAC1_SLP_IE_M, RTC_IO_PDAC1_HOLD_M, RTC_CNTL_PDAC1_HOLD_FORCE_M, RTC_IO_PDAC1_DRV_V, RTC_IO_PDAC1_DRV_S, RTCIO_GPIO25_CHANNEL}, //25
- {RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_MUX_SEL_M, RTC_IO_PDAC2_FUN_SEL_S, RTC_IO_PDAC2_FUN_IE_M, RTC_IO_PDAC2_RUE_M, RTC_IO_PDAC2_RDE_M, RTC_IO_PDAC2_SLP_SEL_M, RTC_IO_PDAC2_SLP_IE_M, RTC_IO_PDAC2_HOLD_M, RTC_CNTL_PDAC2_HOLD_FORCE_M, RTC_IO_PDAC2_DRV_V, RTC_IO_PDAC2_DRV_S, RTCIO_GPIO26_CHANNEL}, //26
- {RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_MUX_SEL_M, RTC_IO_TOUCH_PAD7_FUN_SEL_S, RTC_IO_TOUCH_PAD7_FUN_IE_M, RTC_IO_TOUCH_PAD7_RUE_M, RTC_IO_TOUCH_PAD7_RDE_M, RTC_IO_TOUCH_PAD7_SLP_SEL_M, RTC_IO_TOUCH_PAD7_SLP_IE_M, RTC_IO_TOUCH_PAD7_HOLD_M, RTC_CNTL_TOUCH_PAD7_HOLD_FORCE_M, RTC_IO_TOUCH_PAD7_DRV_V, RTC_IO_TOUCH_PAD7_DRV_S, RTCIO_GPIO27_CHANNEL}, //27
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //28
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //29
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //30
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //31
- {RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_MUX_SEL_M, RTC_IO_X32P_FUN_SEL_S, RTC_IO_X32P_FUN_IE_M, RTC_IO_X32P_RUE_M, RTC_IO_X32P_RDE_M, RTC_IO_X32P_SLP_SEL_M, RTC_IO_X32P_SLP_IE_M, RTC_IO_X32P_HOLD_M, RTC_CNTL_X32P_HOLD_FORCE_M, RTC_IO_X32P_DRV_V, RTC_IO_X32P_DRV_S, RTCIO_GPIO32_CHANNEL}, //32
- {RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL_M, RTC_IO_X32N_FUN_SEL_S, RTC_IO_X32N_FUN_IE_M, RTC_IO_X32N_RUE_M, RTC_IO_X32N_RDE_M, RTC_IO_X32N_SLP_SEL_M, RTC_IO_X32N_SLP_IE_M, RTC_IO_X32N_HOLD_M, RTC_CNTL_X32N_HOLD_FORCE_M, RTC_IO_X32N_DRV_V, RTC_IO_X32N_DRV_S, RTCIO_GPIO33_CHANNEL}, //33
- {RTC_IO_ADC_PAD_REG, RTC_IO_ADC1_MUX_SEL_M, RTC_IO_ADC1_FUN_SEL_S, RTC_IO_ADC1_FUN_IE_M, 0, 0, RTC_IO_ADC1_SLP_SEL_M, RTC_IO_ADC1_SLP_IE_M, RTC_IO_ADC1_HOLD_M, RTC_CNTL_ADC1_HOLD_FORCE_M, 0, 0, RTCIO_GPIO34_CHANNEL}, //34
- {RTC_IO_ADC_PAD_REG, RTC_IO_ADC2_MUX_SEL_M, RTC_IO_ADC2_FUN_SEL_S, RTC_IO_ADC2_FUN_IE_M, 0, 0, RTC_IO_ADC2_SLP_SEL_M, RTC_IO_ADC2_SLP_IE_M, RTC_IO_ADC1_HOLD_M, RTC_CNTL_ADC2_HOLD_FORCE_M, 0, 0, RTCIO_GPIO35_CHANNEL}, //35
- {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE1_MUX_SEL_M, RTC_IO_SENSE1_FUN_SEL_S, RTC_IO_SENSE1_FUN_IE_M, 0, 0, RTC_IO_SENSE1_SLP_SEL_M, RTC_IO_SENSE1_SLP_IE_M, RTC_IO_SENSE1_HOLD_M, RTC_CNTL_SENSE1_HOLD_FORCE_M, 0, 0, RTCIO_GPIO36_CHANNEL}, //36
- {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE2_MUX_SEL_M, RTC_IO_SENSE2_FUN_SEL_S, RTC_IO_SENSE2_FUN_IE_M, 0, 0, RTC_IO_SENSE2_SLP_SEL_M, RTC_IO_SENSE2_SLP_IE_M, RTC_IO_SENSE1_HOLD_M, RTC_CNTL_SENSE2_HOLD_FORCE_M, 0, 0, RTCIO_GPIO37_CHANNEL}, //37
- {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE3_MUX_SEL_M, RTC_IO_SENSE3_FUN_SEL_S, RTC_IO_SENSE3_FUN_IE_M, 0, 0, RTC_IO_SENSE3_SLP_SEL_M, RTC_IO_SENSE3_SLP_IE_M, RTC_IO_SENSE1_HOLD_M, RTC_CNTL_SENSE3_HOLD_FORCE_M, 0, 0, RTCIO_GPIO38_CHANNEL}, //38
- {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE4_MUX_SEL_M, RTC_IO_SENSE4_FUN_SEL_S, RTC_IO_SENSE4_FUN_IE_M, 0, 0, RTC_IO_SENSE4_SLP_SEL_M, RTC_IO_SENSE4_SLP_IE_M, RTC_IO_SENSE1_HOLD_M, RTC_CNTL_SENSE4_HOLD_FORCE_M, 0, 0, RTCIO_GPIO39_CHANNEL}, //39
-};
-
typedef enum {
ADC_CTRL_RTC = 0,
ADC_CTRL_ULP = 1,
@@ -519,7 +479,7 @@ static void touch_pad_filter_cb(void *arg)
{
static uint32_t s_filtered_temp[TOUCH_PAD_MAX] = {0};
- if (s_touch_pad_filter == NULL) {
+ if (s_touch_pad_filter == NULL || rtc_touch_mux == NULL) {
return;
}
uint16_t val = 0;
@@ -820,16 +780,28 @@ esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold)
{
RTC_MODULE_CHECK(rtc_touch_mux != NULL, "Touch pad not initialized", ESP_FAIL);
RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG);
- s_touch_pad_init_bit |= (1 << touch_num);
+ touch_fsm_mode_t mode;
touch_pad_set_thresh(touch_num, threshold);
touch_pad_io_init(touch_num);
touch_pad_set_cnt_mode(touch_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_LOW);
- touch_fsm_mode_t mode;
touch_pad_get_fsm_mode(&mode);
if (TOUCH_FSM_MODE_SW == mode) {
touch_pad_clear_group_mask((1 << touch_num), (1 << touch_num), (1 << touch_num));
+ s_touch_pad_init_bit |= (1 << touch_num);
} else if (TOUCH_FSM_MODE_TIMER == mode){
+ uint16_t sleep_time = 0;
+ uint16_t meas_cycle = 0;
+ uint32_t wait_time_ms = 0;
+ uint32_t wait_tick = 0;
+ uint32_t rtc_clk = rtc_clk_slow_freq_get_hz();
touch_pad_set_group_mask((1 << touch_num), (1 << touch_num), (1 << touch_num));
+ touch_pad_get_meas_time(&sleep_time, &meas_cycle);
+ //If the FSM mode is 'TOUCH_FSM_MODE_TIMER', The data will be ready after one measurement cycle
+ //after this function is executed, otherwise, the "touch_value" by "touch_pad_read" is 0.
+ wait_time_ms = sleep_time/(rtc_clk/1000) + meas_cycle/(RTC_FAST_CLK_FREQ_APPROX/1000);
+ wait_tick = wait_time_ms/portTICK_RATE_MS;
+ vTaskDelay(wait_tick ? wait_tick : 1);
+ s_touch_pad_init_bit |= (1 << touch_num);
} else {
return ESP_FAIL;
}
@@ -846,24 +818,27 @@ esp_err_t touch_pad_init()
}
touch_pad_intr_disable();
touch_pad_clear_group_mask(TOUCH_PAD_BIT_MASK_MAX, TOUCH_PAD_BIT_MASK_MAX, TOUCH_PAD_BIT_MASK_MAX);
- touch_pad_set_fsm_mode(TOUCH_FSM_MODE_DEFAULT);
touch_pad_set_trigger_mode(TOUCH_TRIGGER_MODE_DEFAULT);
touch_pad_set_trigger_source(TOUCH_TRIGGER_SOURCE_DEFAULT);
touch_pad_clear_status();
touch_pad_set_meas_time(TOUCH_PAD_SLEEP_CYCLE_DEFAULT, TOUCH_PAD_MEASURE_CYCLE_DEFAULT);
+ touch_pad_set_fsm_mode(TOUCH_FSM_MODE_DEFAULT);
return ESP_OK;
}
esp_err_t touch_pad_deinit()
{
- if (rtc_touch_mux == NULL) {
- return ESP_FAIL;
+ RTC_MODULE_CHECK(rtc_touch_mux != NULL, "Touch pad not initialized", ESP_FAIL);
+ if (s_touch_pad_filter != NULL) {
+ touch_pad_filter_stop();
+ touch_pad_filter_delete();
}
+ xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
s_touch_pad_init_bit = 0x0000;
- touch_pad_filter_delete();
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW);
touch_pad_clear_status();
touch_pad_intr_disable();
+ xSemaphoreGive(rtc_touch_mux);
vSemaphoreDelete(rtc_touch_mux);
rtc_touch_mux = NULL;
return ESP_OK;
@@ -890,6 +865,9 @@ static esp_err_t _touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value, t
} else {
res = ESP_FAIL;
}
+ if (*touch_value == 0) {
+ res = ESP_ERR_INVALID_STATE;
+ }
return res;
}
@@ -913,8 +891,11 @@ IRAM_ATTR esp_err_t touch_pad_read_raw_data(touch_pad_t touch_num, uint16_t *tou
RTC_MODULE_CHECK(rtc_touch_mux != NULL, "Touch pad not initialized", ESP_FAIL);
RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(touch_value != NULL, "touch_value", ESP_ERR_INVALID_ARG);
- RTC_MODULE_CHECK(s_touch_pad_filter != NULL, "Touch pad filter not initialized", ESP_ERR_INVALID_STATE);
+ RTC_MODULE_CHECK(s_touch_pad_filter != NULL, "Touch pad filter not initialized", ESP_FAIL);
*touch_value = s_touch_pad_filter->raw_val[touch_num];
+ if (*touch_value == 0) {
+ return ESP_ERR_INVALID_STATE;
+ }
return ESP_OK;
}
@@ -923,8 +904,11 @@ IRAM_ATTR esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *tou
RTC_MODULE_CHECK(rtc_touch_mux != NULL, "Touch pad not initialized", ESP_FAIL);
RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(touch_value != NULL, "touch_value", ESP_ERR_INVALID_ARG);
- RTC_MODULE_CHECK(s_touch_pad_filter != NULL, "Touch pad filter not initialized", ESP_ERR_INVALID_STATE);
+ RTC_MODULE_CHECK(s_touch_pad_filter != NULL, "Touch pad filter not initialized", ESP_FAIL);
*touch_value = (s_touch_pad_filter->filtered_val[touch_num]);
+ if (*touch_value == 0) {
+ return ESP_ERR_INVALID_STATE;
+ }
return ESP_OK;
}
@@ -984,20 +968,17 @@ esp_err_t touch_pad_filter_start(uint32_t filter_period_ms)
if (s_touch_pad_filter->timer == NULL) {
ret = ESP_ERR_NO_MEM;
}
- xTimerStart(s_touch_pad_filter->timer, portMAX_DELAY);
- } else {
- xTimerChangePeriod(s_touch_pad_filter->timer, filter_period_ms / portTICK_PERIOD_MS, portMAX_DELAY);
s_touch_pad_filter->period = filter_period_ms;
- xTimerStart(s_touch_pad_filter->timer, portMAX_DELAY);
}
xSemaphoreGive(rtc_touch_mux);
+ touch_pad_filter_cb(NULL);
return ret;
}
esp_err_t touch_pad_filter_stop()
{
RTC_MODULE_CHECK(s_touch_pad_filter != NULL, "Touch pad filter not initialized", ESP_ERR_INVALID_STATE);
-
+ RTC_MODULE_CHECK(rtc_touch_mux != NULL, "Touch pad not initialized", ESP_ERR_INVALID_STATE);
esp_err_t ret = ESP_OK;
xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
if (s_touch_pad_filter != NULL) {
@@ -1013,6 +994,7 @@ esp_err_t touch_pad_filter_stop()
esp_err_t touch_pad_filter_delete()
{
RTC_MODULE_CHECK(s_touch_pad_filter != NULL, "Touch pad filter not initialized", ESP_ERR_INVALID_STATE);
+ RTC_MODULE_CHECK(rtc_touch_mux != NULL, "Touch pad not initialized", ESP_ERR_INVALID_STATE);
xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
if (s_touch_pad_filter != NULL) {
if (s_touch_pad_filter->timer != NULL) {
@@ -1027,6 +1009,16 @@ esp_err_t touch_pad_filter_delete()
return ESP_OK;
}
+esp_err_t touch_pad_get_wakeup_status(touch_pad_t *pad_num)
+{
+ uint32_t touch_mask = SENS.sar_touch_ctrl2.touch_meas_en;
+ if(touch_mask == 0) {
+ return ESP_FAIL;
+ }
+ *pad_num = touch_pad_num_wrap((touch_pad_t)(__builtin_ffs(touch_mask) - 1));
+ return ESP_OK;
+}
+
/*---------------------------------------------------------------
ADC Common
---------------------------------------------------------------*/
@@ -2008,6 +2000,7 @@ esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg)
SLIST_REMOVE_AFTER(prev, next);
}
found = true;
+ free(it);
break;
}
prev = it;
diff --git a/components/driver/sdio_slave.c b/components/driver/sdio_slave.c
index b63b5c677a..05518f83f7 100644
--- a/components/driver/sdio_slave.c
+++ b/components/driver/sdio_slave.c
@@ -86,23 +86,21 @@ The driver of FIFOs works as below:
#include
#include "driver/sdio_slave.h"
-#include "soc/slc_struct.h"
-#include "soc/slc_reg.h"
-#include "soc/host_struct.h"
-#include "soc/hinf_struct.h"
+#include "soc/sdio_slave_periph.h"
#include "rom/lldesc.h"
#include "esp_log.h"
#include "esp_intr_alloc.h"
#include "freertos/FreeRTOS.h"
#include "soc/dport_access.h"
#include "soc/dport_reg.h"
+#include "soc/io_mux_reg.h"
#include "freertos/semphr.h"
#include "xtensa/core-macros.h"
#include "driver/periph_ctrl.h"
#define SDIO_SLAVE_CHECK(res, str, ret_val) do { if(!(res)){\
- SDIO_SLAVE_LOGE( "%s", str);\
+ SDIO_SLAVE_LOGE("%s", str);\
return ret_val;\
} }while (0)
@@ -118,41 +116,6 @@ typedef enum {
STATE_SENDING = 3,
} send_state_t;
-typedef struct {
- uint32_t clk;
- uint32_t cmd;
- uint32_t d0;
- uint32_t d1;
- uint32_t d2;
- uint32_t d3;
- int func;
-} sdio_slave_slot_info_t ;
-
-// I/O slot of sdio slave:
-// 0: GPIO 6, 11, 7, 8, 9, 10,
-// 1: GPIO 14, 15, 2, 4, 12, 13 for CLK, CMD, D0, D1, D2, D3 respectively.
-// only one peripheral for SDIO and only one slot can work at the same time.
-// currently slot 0 is occupied by SPI for flash
-static const sdio_slave_slot_info_t s_slot_info[2] = {
- {
- .clk = PERIPHS_IO_MUX_SD_CLK_U,
- .cmd = PERIPHS_IO_MUX_SD_CMD_U,
- .d0 = PERIPHS_IO_MUX_SD_DATA0_U,
- .d1 = PERIPHS_IO_MUX_SD_DATA1_U,
- .d2 = PERIPHS_IO_MUX_SD_DATA2_U,
- .d3 = PERIPHS_IO_MUX_SD_DATA3_U,
- .func = 0,
- }, {
- .clk = PERIPHS_IO_MUX_MTMS_U,
- .cmd = PERIPHS_IO_MUX_MTDO_U,
- .d0 = PERIPHS_IO_MUX_GPIO2_U,
- .d1 = PERIPHS_IO_MUX_GPIO4_U,
- .d2 = PERIPHS_IO_MUX_MTDI_U,
- .d3 = PERIPHS_IO_MUX_MTCK_U,
- .func = 4,
- },
-};
-
// first 3 WORDs of this struct is defined by and compatible to the DMA link list format.
// sdio_slave_buf_handle_t is of type buf_desc_t*;
typedef struct buf_desc_s{
@@ -178,8 +141,8 @@ typedef struct buf_desc_s{
void* arg; /* to hold some parameters */
} buf_desc_t;
-typedef STAILQ_HEAD( bufdesc_stailq_head_s, buf_desc_s ) buf_stailq_t;
-typedef TAILQ_HEAD( bufdesc_tailq_head_s, buf_desc_s ) buf_tailq_t;
+typedef STAILQ_HEAD(bufdesc_stailq_head_s, buf_desc_s) buf_stailq_t;
+typedef TAILQ_HEAD(bufdesc_tailq_head_s, buf_desc_s) buf_tailq_t;
typedef struct {
uint8_t* data;
@@ -192,7 +155,7 @@ typedef struct {
SemaphoreHandle_t remain_cnt;
} sdio_ringbuf_t;
-#define offset_of(type, field) ( (unsigned int)&(((type *)(0))->field) )
+#define offset_of(type, field) ((unsigned int)&(((type *)(0))->field))
typedef enum {
ringbuf_write_ptr = offset_of(sdio_ringbuf_t, write_ptr),
ringbuf_read_ptr = offset_of(sdio_ringbuf_t, read_ptr),
@@ -224,7 +187,7 @@ typedef struct {
/*------- receiving ---------------*/
buf_stailq_t recv_link_list; // now ready to/already hold data
buf_tailq_t recv_reg_list; // removed from the link list, registered but not used now
- buf_desc_t* recv_cur_ret;
+ volatile buf_desc_t* recv_cur_ret; // next desc to return, NULL if all loaded descriptors are returned
portMUX_TYPE recv_spinlock;
} sdio_context_t;
@@ -273,15 +236,15 @@ typedef enum {
static void sdio_ringbuf_deinit(sdio_ringbuf_t* buf)
{
- if ( buf->remain_cnt != NULL ) vSemaphoreDelete( buf->remain_cnt );
- if ( buf->data != NULL ) free(buf->data);
+ if (buf->remain_cnt != NULL) vSemaphoreDelete(buf->remain_cnt);
+ if (buf->data != NULL) free(buf->data);
*buf = SDIO_RINGBUF_INITIALIZER();
}
static esp_err_t sdio_ringbuf_init(sdio_ringbuf_t* buf, int item_size, int item_cnt)
{
- if (buf->data != NULL ) {
- SDIO_SLAVE_LOGE( "sdio_ringbuf_init: already initialized");
+ if (buf->data != NULL) {
+ SDIO_SLAVE_LOGE("sdio_ringbuf_init: already initialized");
return ESP_ERR_INVALID_STATE;
}
buf->item_size = item_size;
@@ -289,9 +252,9 @@ static esp_err_t sdio_ringbuf_init(sdio_ringbuf_t* buf, int item_size, int item_
buf->size = item_size * (item_cnt+1);
//apply for resources
buf->data = (uint8_t*)malloc(buf->size);
- if ( buf->data == NULL ) goto no_mem;
- buf->remain_cnt = xSemaphoreCreateCounting( item_cnt, item_cnt );
- if ( buf->remain_cnt == NULL ) goto no_mem;
+ if (buf->data == NULL) goto no_mem;
+ buf->remain_cnt = xSemaphoreCreateCounting(item_cnt, item_cnt);
+ if (buf->remain_cnt == NULL) goto no_mem;
//initialize pointers
buf->write_ptr = buf->data;
buf->read_ptr = buf->data;
@@ -303,7 +266,7 @@ no_mem:
}
//calculate a pointer with offset to a original pointer of the specific ringbuffer
-static inline uint8_t* sdio_ringbuf_offset_ptr( sdio_ringbuf_t *buf, sdio_ringbuf_pointer_t ptr, uint32_t offset )
+static inline uint8_t* sdio_ringbuf_offset_ptr(sdio_ringbuf_t *buf, sdio_ringbuf_pointer_t ptr, uint32_t offset)
{
uint8_t *buf_ptr = (uint8_t*)*(uint32_t*)(((uint8_t*)buf)+ptr); //get the specific pointer of the buffer
uint8_t *offset_ptr=buf_ptr+offset;
@@ -311,21 +274,21 @@ static inline uint8_t* sdio_ringbuf_offset_ptr( sdio_ringbuf_t *buf, sdio_ringbu
return offset_ptr;
}
-static esp_err_t sdio_ringbuf_send( sdio_ringbuf_t* buf, esp_err_t (*copy_callback)(uint8_t*, void*), void* arg, TickType_t wait )
+static esp_err_t sdio_ringbuf_send(sdio_ringbuf_t* buf, esp_err_t (*copy_callback)(uint8_t*, void*), void* arg, TickType_t wait)
{
portBASE_TYPE ret = xSemaphoreTake(buf->remain_cnt, wait);
- if ( ret != pdTRUE ) return NULL;
+ if (ret != pdTRUE) return ESP_ERR_TIMEOUT;
- portENTER_CRITICAL( &buf->write_spinlock );
- uint8_t* get_ptr = sdio_ringbuf_offset_ptr( buf, ringbuf_write_ptr, buf->item_size );
+ portENTER_CRITICAL(&buf->write_spinlock);
+ uint8_t* get_ptr = sdio_ringbuf_offset_ptr(buf, ringbuf_write_ptr, buf->item_size);
esp_err_t err = ESP_OK;
if (copy_callback) (*copy_callback)(get_ptr, arg);
- if ( err != ESP_OK ) {
- portEXIT_CRITICAL( &buf->write_spinlock );
+ if (err != ESP_OK) {
+ portEXIT_CRITICAL(&buf->write_spinlock);
return err;
}
buf->write_ptr = get_ptr;
- portEXIT_CRITICAL( &buf->write_spinlock );
+ portEXIT_CRITICAL(&buf->write_spinlock);
return ESP_OK;
}
@@ -333,65 +296,65 @@ static esp_err_t sdio_ringbuf_send( sdio_ringbuf_t* buf, esp_err_t (*copy_callba
// since this is designed to be called in the ISR, no parallel logic
static inline esp_err_t sdio_ringbuf_recv(sdio_ringbuf_t* buf, uint8_t **start, uint8_t **end, ringbuf_get_all_t get_all, TickType_t wait)
{
- assert( buf->free_ptr == buf->read_ptr ); //must return before recv again
+ assert(buf->free_ptr == buf->read_ptr); //must return before recv again
assert(wait == 0); //only implement wait = 0 case now
- if ( start == NULL && end == NULL ) return ESP_ERR_INVALID_ARG; // must have a output
- if ( buf->read_ptr == buf->write_ptr ) return ESP_ERR_NOT_FOUND; // no data
+ if (start == NULL && end == NULL) return ESP_ERR_INVALID_ARG; // must have a output
+ if (buf->read_ptr == buf->write_ptr) return ESP_ERR_NOT_FOUND; // no data
uint8_t *get_start = sdio_ringbuf_offset_ptr(buf, ringbuf_read_ptr, buf->item_size);
- if ( get_all != RINGBUF_GET_ONE ) {
+ if (get_all != RINGBUF_GET_ONE) {
buf->read_ptr = buf->write_ptr;
} else {
buf->read_ptr = get_start;
}
- if ( start != NULL ) *start = get_start;
- if ( end != NULL ) *end = buf->read_ptr;
+ if (start != NULL) *start = get_start;
+ if (end != NULL) *end = buf->read_ptr;
return ESP_OK;
}
static inline void sdio_ringbuf_return_from_isr(sdio_ringbuf_t* buf, uint8_t *ptr, portBASE_TYPE *yield)
{
- assert( sdio_ringbuf_offset_ptr(buf, ringbuf_free_ptr, buf->item_size) == ptr );
+ assert(sdio_ringbuf_offset_ptr(buf, ringbuf_free_ptr, buf->item_size) == ptr);
int size = (buf->read_ptr + buf->size - buf->free_ptr)%buf->size;
int count = size/buf->item_size;
- assert( count*buf->item_size==size);
+ assert(count*buf->item_size==size);
buf->free_ptr = buf->read_ptr;
- for( int i = 0; i < count; i ++ ) {
- portBASE_TYPE ret = xSemaphoreGiveFromISR( buf->remain_cnt, yield );
- assert( ret == pdTRUE );
+ for(int i = 0; i < count; i++) {
+ portBASE_TYPE ret = xSemaphoreGiveFromISR(buf->remain_cnt, yield);
+ assert(ret == pdTRUE);
}
}
static inline void sdio_ringbuf_return(sdio_ringbuf_t* buf, uint8_t *ptr)
{
- assert( sdio_ringbuf_offset_ptr(buf, ringbuf_free_ptr, buf->item_size) == ptr );
+ assert(sdio_ringbuf_offset_ptr(buf, ringbuf_free_ptr, buf->item_size) == ptr);
int size = (buf->read_ptr + buf->size - buf->free_ptr)%buf->size;
int count = size/buf->item_size;
- assert( count*buf->item_size==size);
+ assert(count*buf->item_size==size);
buf->free_ptr = buf->read_ptr;
- for( int i = 0; i < count; i ++ ) {
- portBASE_TYPE ret = xSemaphoreGive( buf->remain_cnt );
- assert( ret == pdTRUE );
+ for(int i = 0; i < count; i++) {
+ portBASE_TYPE ret = xSemaphoreGive(buf->remain_cnt);
+ assert(ret == pdTRUE);
}
}
static inline uint8_t* sdio_ringbuf_peek_front(sdio_ringbuf_t* buf)
{
- if ( buf->read_ptr != buf->write_ptr ) {
+ if (buf->read_ptr != buf->write_ptr) {
return sdio_ringbuf_offset_ptr(buf, ringbuf_read_ptr, buf->item_size);
} else {
return NULL;
}
}
-static inline uint8_t* sdio_ringbuf_peek_rear( sdio_ringbuf_t *buf )
+static inline uint8_t* sdio_ringbuf_peek_rear(sdio_ringbuf_t *buf)
{
return buf->write_ptr;
}
-static inline bool sdio_ringbuf_empty( sdio_ringbuf_t* buf )
+static inline bool sdio_ringbuf_empty(sdio_ringbuf_t* buf)
{
return (buf->read_ptr == buf->write_ptr? true : false);
}
@@ -399,15 +362,15 @@ static inline bool sdio_ringbuf_empty( sdio_ringbuf_t* buf )
static inline void show_ll(buf_desc_t *item)
{
- ESP_EARLY_LOGD( TAG, "=> %p: size: %d(%d), eof: %d, owner: %d", item, item->size, item->length, item->eof, item->owner );
- ESP_EARLY_LOGD( TAG, " buf: %p, stqe_next: %p, tqe-prev: %p", item->buf, item->qe.stqe_next, item->te.tqe_prev );
+ ESP_EARLY_LOGD(TAG, "=> %p: size: %d(%d), eof: %d, owner: %d", item, item->size, item->length, item->eof, item->owner);
+ ESP_EARLY_LOGD(TAG, " buf: %p, stqe_next: %p, tqe-prev: %p", item->buf, item->qe.stqe_next, item->te.tqe_prev);
}
static void __attribute((unused)) dump_ll(buf_stailq_t *queue)
{
buf_desc_t *item = NULL;
- ESP_EARLY_LOGD( TAG, ">>>>> first: %p, last: %p <<<<<", queue->stqh_first, queue->stqh_last );
- STAILQ_FOREACH( item, queue, qe ) {
+ ESP_EARLY_LOGD(TAG, ">>>>> first: %p, last: %p <<<<<", queue->stqh_first, queue->stqh_last);
+ STAILQ_FOREACH(item, queue, qe) {
show_ll(item);
}
}
@@ -415,17 +378,17 @@ static void __attribute((unused)) dump_ll(buf_stailq_t *queue)
static inline void deinit_context()
{
context.config = (sdio_slave_config_t){};
- for( int i = 0; i < 9; i ++ ) {
- if ( context.events[i] != NULL ) {
+ for(int i = 0; i < 9; i++) {
+ if (context.events[i] != NULL) {
vSemaphoreDelete(context.events[i]);
context.events[i] = NULL;
}
}
- if ( context.ret_queue != NULL ) {
+ if (context.ret_queue != NULL) {
vQueueDelete(context.ret_queue);
context.ret_queue = NULL;
}
- sdio_ringbuf_deinit( &context.sendbuf );
+ sdio_ringbuf_deinit(&context.sendbuf);
}
esp_err_t link_desc_to_last(uint8_t* desc, void* arg)
@@ -436,58 +399,58 @@ esp_err_t link_desc_to_last(uint8_t* desc, void* arg)
static esp_err_t init_ringbuf()
{
- esp_err_t ret = sdio_ringbuf_init( &context.sendbuf, sizeof(buf_desc_t), context.config.send_queue_size );
- if ( ret != ESP_OK ) return ret;
+ esp_err_t ret = sdio_ringbuf_init(&context.sendbuf, sizeof(buf_desc_t), context.config.send_queue_size);
+ if (ret != ESP_OK) return ret;
esp_err_t rcv_res;
buf_desc_t *first=NULL, *last=NULL;
//no copy for the first descriptor
- ret = sdio_ringbuf_send( &context.sendbuf, NULL, NULL, portMAX_DELAY);
- if ( ret != ESP_OK ) return ret;
+ ret = sdio_ringbuf_send(&context.sendbuf, NULL, NULL, portMAX_DELAY);
+ if (ret != ESP_OK) return ret;
//loop in the ringbuf to link all the desc one after another as a ring
- for ( int i = 0; i < context.config.send_queue_size+1; i++ ) {
- rcv_res = sdio_ringbuf_recv( &context.sendbuf, (uint8_t**)&last, NULL, RINGBUF_GET_ONE, 0 );
- assert ( rcv_res == ESP_OK );
- ret = sdio_ringbuf_send( &context.sendbuf, link_desc_to_last, last, portMAX_DELAY);
- if ( ret != ESP_OK ) return ret;
+ for (int i = 0; i < context.config.send_queue_size+1; i++) {
+ rcv_res = sdio_ringbuf_recv(&context.sendbuf, (uint8_t**)&last, NULL, RINGBUF_GET_ONE, 0);
+ assert (rcv_res == ESP_OK);
+ ret = sdio_ringbuf_send(&context.sendbuf, link_desc_to_last, last, portMAX_DELAY);
+ if (ret != ESP_OK) return ret;
sdio_ringbuf_return(&context.sendbuf, (uint8_t*)last);
}
first = NULL;
last = NULL;
//clear the queue
- rcv_res = sdio_ringbuf_recv( &context.sendbuf, (uint8_t**)&first, (uint8_t**)&last, RINGBUF_GET_ALL, 0 );
- assert ( rcv_res == ESP_OK );
- assert( first == last ); //there should be only one desc remain
- sdio_ringbuf_return(&context.sendbuf, (uint8_t*)first );
+ rcv_res = sdio_ringbuf_recv(&context.sendbuf, (uint8_t**)&first, (uint8_t**)&last, RINGBUF_GET_ALL, 0);
+ assert (rcv_res == ESP_OK);
+ assert(first == last); //there should be only one desc remain
+ sdio_ringbuf_return(&context.sendbuf, (uint8_t*)first);
return ESP_OK;
}
static esp_err_t init_context(sdio_slave_config_t *config)
{
- SDIO_SLAVE_CHECK( *(uint32_t*)&context.config == 0, "sdio slave already initialized", ESP_ERR_INVALID_STATE );
+ SDIO_SLAVE_CHECK(*(uint32_t*)&context.config == 0, "sdio slave already initialized", ESP_ERR_INVALID_STATE);
context.config = *config;
// in theory we can queue infinite buffers in the linked list, but for multi-core reason we have to use a queue to
// count the finished buffers.
- context.recv_event = xSemaphoreCreateCounting(UINT32_MAX, 0 );
- for( int i = 0; i < 9; i ++ ) {
- if ( i < 8 ) {
+ context.recv_event = xSemaphoreCreateCounting(UINT32_MAX, 0);
+ for(int i = 0; i < 9; i++) {
+ if (i < 8) {
context.events[i] = xSemaphoreCreateBinary();
} //for 8, already created.
- if ( context.events[i] == NULL ) {
- SDIO_SLAVE_LOGE( "event initialize failed");
+ if (context.events[i] == NULL) {
+ SDIO_SLAVE_LOGE("event initialize failed");
goto no_mem;
}
}
esp_err_t ret = init_ringbuf();
- if ( ret != ESP_OK ) goto no_mem;
+ if (ret != ESP_OK) goto no_mem;
- context.ret_queue = xQueueCreate( config->send_queue_size, sizeof(void*) );
- if ( context.ret_queue == NULL ) goto no_mem;
+ context.ret_queue = xQueueCreate(config->send_queue_size, sizeof(void*));
+ if (context.ret_queue == NULL) goto no_mem;
context.recv_link_list = (buf_stailq_t)STAILQ_HEAD_INITIALIZER(context.recv_link_list);
context.recv_reg_list = (buf_tailq_t)TAILQ_HEAD_INITIALIZER(context.recv_reg_list);
@@ -498,13 +461,21 @@ no_mem:
return ESP_ERR_NO_MEM;
}
-static inline void configure_pin(uint32_t io_mux_reg, uint32_t func)
+static void configure_pin(int pin, uint32_t func, bool pullup)
{
const int sdmmc_func = func;
const int drive_strength = 3;
- PIN_INPUT_ENABLE(io_mux_reg);
- PIN_FUNC_SELECT(io_mux_reg, sdmmc_func);
- PIN_SET_DRV(io_mux_reg, drive_strength);
+ assert(pin!=-1);
+ uint32_t reg = GPIO_PIN_MUX_REG[pin];
+ assert(reg!=UINT32_MAX);
+
+ PIN_INPUT_ENABLE(reg);
+ PIN_FUNC_SELECT(reg, sdmmc_func);
+ PIN_SET_DRV(reg, drive_strength);
+ gpio_pulldown_dis(pin);
+ if (pullup) {
+ gpio_pullup_en(pin);
+ }
}
static inline esp_err_t sdio_slave_hw_init(sdio_slave_config_t *config)
@@ -513,13 +484,20 @@ static inline esp_err_t sdio_slave_hw_init(sdio_slave_config_t *config)
SLC.slc0_int_ena.val = 0;
//initialize pin
- const sdio_slave_slot_info_t *slot = &s_slot_info[1];
- configure_pin(slot->clk, slot->func);
- configure_pin(slot->cmd, slot->func);
- configure_pin(slot->d0, slot->func);
- configure_pin(slot->d1, slot->func);
- configure_pin(slot->d2, slot->func);
- configure_pin(slot->d3, slot->func);
+ const sdio_slave_slot_info_t *slot = &sdio_slave_slot_info[1];
+
+ bool pullup = config->flags & SDIO_SLAVE_FLAG_INTERNAL_PULLUP;
+ configure_pin(slot->clk_gpio, slot->func, false); //clk doesn't need a pullup
+ configure_pin(slot->cmd_gpio, slot->func, pullup);
+ configure_pin(slot->d0_gpio, slot->func, pullup);
+ if ((config->flags & SDIO_SLAVE_FLAG_HOST_INTR_DISABLED)==0) {
+ configure_pin(slot->d1_gpio, slot->func, pullup);
+ }
+ if ((config->flags & SDIO_SLAVE_FLAG_DAT2_DISABLED)==0) {
+ configure_pin(slot->d2_gpio, slot->func, pullup);
+ }
+ configure_pin(slot->d3_gpio, slot->func, pullup);
+
//enable module and config
periph_module_reset(PERIPH_SDIO_SLAVE_MODULE);
periph_module_enable(PERIPH_SDIO_SLAVE_MODULE);
@@ -536,30 +514,30 @@ static inline esp_err_t sdio_slave_hw_init(sdio_slave_config_t *config)
SLC.rx_dscr_conf.slc0_token_no_replace = 1;
HINF.cfg_data1.highspeed_enable = 1;
- switch( config->timing ) {
+ switch(config->timing) {
case SDIO_SLAVE_TIMING_PSEND_PSAMPLE:
- HOST.conf.frc_sdio20 = 0xf;
+ HOST.conf.frc_sdio20 = 0x1f;
HOST.conf.frc_sdio11 = 0;
- HOST.conf.frc_pos_samp = 0xf;
+ HOST.conf.frc_pos_samp = 0x1f;
HOST.conf.frc_neg_samp = 0;
break;
case SDIO_SLAVE_TIMING_PSEND_NSAMPLE:
- HOST.conf.frc_sdio20 = 0xf;
+ HOST.conf.frc_sdio20 = 0x1f;
HOST.conf.frc_sdio11 = 0;
HOST.conf.frc_pos_samp = 0;
- HOST.conf.frc_neg_samp = 0xf;
+ HOST.conf.frc_neg_samp = 0x1f;
break;
case SDIO_SLAVE_TIMING_NSEND_PSAMPLE:
HOST.conf.frc_sdio20 = 0;
- HOST.conf.frc_sdio11 = 0xf;
- HOST.conf.frc_pos_samp = 0xf;
+ HOST.conf.frc_sdio11 = 0x1f;
+ HOST.conf.frc_pos_samp = 0x1f;
HOST.conf.frc_neg_samp = 0;
break;
case SDIO_SLAVE_TIMING_NSEND_NSAMPLE:
HOST.conf.frc_sdio20 = 0;
- HOST.conf.frc_sdio11 = 0xf;
+ HOST.conf.frc_sdio11 = 0x1f;
HOST.conf.frc_pos_samp = 0;
- HOST.conf.frc_neg_samp = 0xf;
+ HOST.conf.frc_neg_samp = 0x1f;
break;
}
@@ -581,12 +559,12 @@ esp_err_t sdio_slave_initialize(sdio_slave_config_t *config)
intr_handle_t intr_handle = NULL;
const int flags = 0;
r = esp_intr_alloc(ETS_SLC0_INTR_SOURCE, flags, sdio_intr, NULL, &intr_handle);
- if (r != ESP_OK ) return r;
+ if (r != ESP_OK) return r;
r = sdio_slave_hw_init(config);
- if ( r != ESP_OK ) return r;
+ if (r != ESP_OK) return r;
r = init_context(config);
- if ( r != ESP_OK ) return r;
+ if (r != ESP_OK) return r;
context.intr_handle = intr_handle;
sdio_slave_reset();
@@ -606,9 +584,9 @@ esp_err_t sdio_slave_start()
esp_err_t ret;
HOST.slc0_int_clr.val = UINT32_MAX;//clear all interrupts
ret = send_start();
- if ( ret != ESP_OK ) return ret;
+ if (ret != ESP_OK) return ret;
ret = recv_start();
- if ( ret != ESP_OK ) return ret;
+ if (ret != ESP_OK) return ret;
HINF.cfg_data1.sdio_ioready1 = 1; //set IO ready to 1 to allow host to use
return ESP_OK;
}
@@ -638,11 +616,11 @@ static void sdio_intr(void* arg)
{
uint32_t int_val = SLC.slc0_int_st.val;
uint32_t int_raw = SLC.slc0_int_raw.val;
- ESP_EARLY_LOGV( TAG, "sdio_intr: %08X(%08X)", int_val, int_raw );
+ ESP_EARLY_LOGV(TAG, "sdio_intr: %08X(%08X)", int_val, int_raw);
- if ( int_val & SDIO_SLAVE_SLC_INT_RX_MASK ) sdio_intr_send(arg);
- if ( int_val & SDIO_SLAVE_SLC_INT_TX_MASK ) sdio_intr_recv(arg);
- if ( int_val & SDIO_SLAVE_SLC_INT_HOST_MASK ) sdio_intr_host(arg);
+ if (int_val & SDIO_SLAVE_SLC_INT_RX_MASK) sdio_intr_send(arg);
+ if (int_val & SDIO_SLAVE_SLC_INT_TX_MASK) sdio_intr_recv(arg);
+ if (int_val & SDIO_SLAVE_SLC_INT_HOST_MASK) sdio_intr_host(arg);
}
/*---------------------------------------------------------------------------
@@ -654,47 +632,47 @@ static void sdio_intr_host(void* arg)
portBASE_TYPE yield = pdFALSE;
SLC.slc0_int_clr.val = int_val;
- for( int i = 0; i < 8; i ++ ) {
- if ( BIT(i) & int_val ) {
- if ( context.config.event_cb != NULL ) (*context.config.event_cb)(i);
- xSemaphoreGiveFromISR( context.events[i], &yield );
+ for(int i = 0; i < 8; i++) {
+ if (BIT(i) & int_val) {
+ if (context.config.event_cb != NULL) (*context.config.event_cb)(i);
+ xSemaphoreGiveFromISR(context.events[i], &yield);
}
}
- if ( yield ) portYIELD_FROM_ISR();
+ if (yield) portYIELD_FROM_ISR();
}
esp_err_t sdio_slave_wait_int(int pos, TickType_t wait)
{
- SDIO_SLAVE_CHECK( pos >= 0 && pos < 8, "interrupt num invalid", ESP_ERR_INVALID_ARG);
- return xSemaphoreTake( context.events[pos], wait );
+ SDIO_SLAVE_CHECK(pos >= 0 && pos < 8, "interrupt num invalid", ESP_ERR_INVALID_ARG);
+ return xSemaphoreTake(context.events[pos], wait);
}
uint8_t sdio_slave_read_reg(int pos)
{
- if ( pos >= 28 && pos <= 31 ) SDIO_SLAVE_LOGW( "%s: interrupt reg, for reference", __FUNCTION__ );
- if ( pos < 0 || pos >= 64 ) SDIO_SLAVE_LOGE( "read register address wrong");
+ if (pos >= 28 && pos <= 31) SDIO_SLAVE_LOGW("%s: interrupt reg, for reference", __FUNCTION__);
+ if (pos < 0 || pos >= 64) SDIO_SLAVE_LOGE("read register address wrong");
return *(uint8_t*)(HOST_SLCHOST_CONF_W_REG(pos));
}
esp_err_t sdio_slave_write_reg(int pos, uint8_t reg)
{
- if ( pos >= 28 && pos <= 31 ) {
- SDIO_SLAVE_LOGE( "interrupt reg, please use sdio_slave_clear_int" );
+ if (pos >= 28 && pos <= 31) {
+ SDIO_SLAVE_LOGE("interrupt reg, please use sdio_slave_clear_int");
return ESP_ERR_INVALID_ARG;
}
- if ( pos < 0 || pos >= 64 ) {
- SDIO_SLAVE_LOGE( "write register address wrong");
+ if (pos < 0 || pos >= 64) {
+ SDIO_SLAVE_LOGE("write register address wrong");
return ESP_ERR_INVALID_ARG;
}
uint32_t addr = HOST_SLCHOST_CONF_W_REG(pos) & (~3);
uint32_t shift = (pos % 4)*8;
- portENTER_CRITICAL( &context.reg_spinlock );
+ portENTER_CRITICAL(&context.reg_spinlock);
int val = *(uint32_t*)addr;
*(uint32_t*)addr = (val & ~(0xff << shift)) | (reg<arg);
- ret = xQueueSendFromISR( context.ret_queue, &desc->arg, yield );
+ ret = xQueueSendFromISR(context.ret_queue, &desc->arg, yield);
assert(ret == pdTRUE);
buf_desc_t* next = STAILQ_NEXT(desc, qe);
desc = next;
} while(desc!=NULL);
- STAILQ_NEXT( context.in_flight_end, qe ) = context.in_flight_next;
+ STAILQ_NEXT(context.in_flight_end, qe) = context.in_flight_next;
sdio_ringbuf_return_from_isr(&context.sendbuf, (uint8_t*)context.in_flight, yield);
context.in_flight = NULL;
context.in_flight_end = NULL;
// Go to wait for packet state
- send_set_state( STATE_WAIT_FOR_START );
+ send_set_state(STATE_WAIT_FOR_START);
return ESP_OK;
}
@@ -852,12 +830,12 @@ static inline esp_err_t send_isr_check_new_pkt(portBASE_TYPE *yield)
esp_err_t ret;
buf_desc_t *start = NULL;
buf_desc_t *end = NULL;
- if ( context.config.sending_mode == SDIO_SLAVE_SEND_PACKET ) {
- ret = sdio_ringbuf_recv( &context.sendbuf, (uint8_t**)&start, (uint8_t**)&end, RINGBUF_GET_ONE, 0);
+ if (context.config.sending_mode == SDIO_SLAVE_SEND_PACKET) {
+ ret = sdio_ringbuf_recv(&context.sendbuf, (uint8_t**)&start, (uint8_t**)&end, RINGBUF_GET_ONE, 0);
} else { //stream mode
- ret = sdio_ringbuf_recv( &context.sendbuf, (uint8_t**)&start, (uint8_t**)&end, RINGBUF_GET_ALL, 0);
+ ret = sdio_ringbuf_recv(&context.sendbuf, (uint8_t**)&start, (uint8_t**)&end, RINGBUF_GET_ALL, 0);
}
- if ( ret == ESP_OK ) {
+ if (ret == ESP_OK) {
context.in_flight = start;
context.in_flight_end = end;
end->eof = 1;
@@ -877,12 +855,12 @@ static inline esp_err_t send_isr_new_packet()
assert(start_desc != NULL && end_desc != NULL);
send_stop_ll_operation();
- send_start_transmission( start_desc );
+ send_start_transmission(start_desc);
// update pkt_len register to allow host reading.
- send_length_write( end_desc->pkt_len );
+ send_length_write(end_desc->pkt_len);
- send_set_state( STATE_SENDING );
+ send_set_state(STATE_SENDING);
ESP_EARLY_LOGD(TAG, "restart new send: %p->%p, pkt_len: %d", start_desc, end_desc, end_desc->pkt_len);
return ESP_OK;
@@ -894,26 +872,26 @@ static void sdio_intr_send(void* arg)
portBASE_TYPE yield = pdFALSE;
// this interrupt is abused to get ISR invoked by app
- if ( SLC.slc0_int_st.rx_done ) SLC.slc0_int_ena.rx_done = 0;
+ if (SLC.slc0_int_st.rx_done) SLC.slc0_int_ena.rx_done = 0;
// Goto idle state (cur_start=NULL) if transmission done,
// also update sequence and recycle descs.
- if ( SLC.slc0_int_st.rx_eof ) {
+ if (SLC.slc0_int_st.rx_eof) {
SLC.slc0_int_clr.rx_eof = 1;
//check current state
- assert( send_get_state() == STATE_SENDING );// context.send_start != NOT_YET && context.send_end != NOT_YET );
+ assert(send_get_state() == STATE_SENDING);// context.send_start != NOT_YET && context.send_end != NOT_YET);
send_isr_eof(&yield);
}
// Go to wait sending state (cur_start!=NULL && cur_end==NULL) if not sending and new packet ready.
// Note we may also enter this state by stopping sending in the app.
- if ( send_get_state() == STATE_WAIT_FOR_START ) {
- if ( context.in_flight == NULL ) send_isr_check_new_pkt(&yield);
+ if (send_get_state() == STATE_WAIT_FOR_START) {
+ if (context.in_flight == NULL) send_isr_check_new_pkt(&yield);
// Go to sending state (cur_start and cur_end != NULL) if has packet to send.
- if ( context.in_flight ) send_isr_new_packet();
+ if (context.in_flight) send_isr_new_packet();
}
- if ( yield ) portYIELD_FROM_ISR();
+ if (yield) portYIELD_FROM_ISR();
}
esp_err_t send_write_desc(uint8_t* desc, void* arg)
@@ -924,14 +902,14 @@ esp_err_t send_write_desc(uint8_t* desc, void* arg)
//copy and keep the link
STAILQ_NEXT(new_desc, qe) = STAILQ_NEXT((buf_desc_t*)desc, qe);
- memcpy( desc, new_desc, sizeof(buf_desc_t) );
+ memcpy(desc, new_desc, sizeof(buf_desc_t));
return ESP_OK;
}
esp_err_t sdio_slave_send_queue(uint8_t* addr, size_t len, void* arg, TickType_t wait)
{
- SDIO_SLAVE_CHECK( len > 0, "len <= 0", ESP_ERR_INVALID_ARG );
- SDIO_SLAVE_CHECK( esp_ptr_dma_capable(addr) && (uint32_t)addr%4==0, "buffer to send should be DMA capable and 32-bit aligned",
+ SDIO_SLAVE_CHECK(len > 0, "len <= 0", ESP_ERR_INVALID_ARG);
+ SDIO_SLAVE_CHECK(esp_ptr_dma_capable(addr) && (uint32_t)addr%4==0, "buffer to send should be DMA capable and 32-bit aligned",
ESP_ERR_INVALID_ARG);
buf_desc_t new_desc = {
@@ -945,16 +923,18 @@ esp_err_t sdio_slave_send_queue(uint8_t* addr, size_t len, void* arg, TickType_t
};
esp_err_t ret = sdio_ringbuf_send(&context.sendbuf, send_write_desc, &new_desc, wait);
- if ( ret != ESP_OK ) return ret;
+ if (ret != ESP_OK) return ret;
send_isr_invoke();
return ESP_OK;
}
-esp_err_t sdio_slave_send_get_finished(void** arg, TickType_t wait)
+esp_err_t sdio_slave_send_get_finished(void** out_arg, TickType_t wait)
{
- portBASE_TYPE err = xQueueReceive( context.ret_queue, arg, wait );
- if ( err != pdTRUE ) return ESP_ERR_TIMEOUT;
+ void* arg = NULL;
+ portBASE_TYPE err = xQueueReceive(context.ret_queue, &arg, wait);
+ if (out_arg) *out_arg = arg;
+ if (err != pdTRUE) return ESP_ERR_TIMEOUT;
return ESP_OK;
}
@@ -963,11 +943,11 @@ esp_err_t sdio_slave_transmit(uint8_t* addr, size_t len)
uint32_t timestamp = XTHAL_GET_CCOUNT();
uint32_t ret_stamp;
- esp_err_t err = sdio_slave_send_queue( addr, len, (void*)timestamp, portMAX_DELAY );
- if ( err != ESP_OK ) return err;
- err = sdio_slave_send_get_finished( (void**)&ret_stamp, portMAX_DELAY );
- if ( err != ESP_OK ) return err;
- SDIO_SLAVE_CHECK( ret_stamp == timestamp, "already sent without return before", ESP_ERR_INVALID_STATE);
+ esp_err_t err = sdio_slave_send_queue(addr, len, (void*)timestamp, portMAX_DELAY);
+ if (err != ESP_OK) return err;
+ err = sdio_slave_send_get_finished((void**)&ret_stamp, portMAX_DELAY);
+ if (err != ESP_OK) return err;
+ SDIO_SLAVE_CHECK(ret_stamp == timestamp, "already sent without return before", ESP_ERR_INVALID_STATE);
return ESP_OK;
}
@@ -976,43 +956,43 @@ esp_err_t sdio_slave_transmit(uint8_t* addr, size_t len)
static esp_err_t send_flush_data()
{
//only works in idle state / wait to send state
- SDIO_SLAVE_CHECK( send_get_state() == STATE_IDLE,
- "flush data when transmission started", ESP_ERR_INVALID_STATE );
+ SDIO_SLAVE_CHECK(send_get_state() == STATE_IDLE,
+ "flush data when transmission started", ESP_ERR_INVALID_STATE);
HOST.slc0_int_clr.rx_new_packet = 1;
buf_desc_t *last = NULL;
- if ( context.in_flight ) {
+ if (context.in_flight) {
buf_desc_t *desc = context.in_flight;
- while( desc != NULL ) {
- xQueueSend( context.ret_queue, desc->arg, portMAX_DELAY );
+ while(desc != NULL) {
+ xQueueSend(context.ret_queue, desc->arg, portMAX_DELAY);
last = desc;
desc = STAILQ_NEXT(desc, qe);
}
- STAILQ_NEXT( context.in_flight_end, qe ) = context.in_flight_next;
- sdio_ringbuf_return( &context.sendbuf, (uint8_t*)context.in_flight );
+ STAILQ_NEXT(context.in_flight_end, qe) = context.in_flight_next;
+ sdio_ringbuf_return(&context.sendbuf, (uint8_t*)context.in_flight);
context.in_flight = NULL;
context.in_flight_end = NULL;
}
buf_desc_t *head;
esp_err_t ret = sdio_ringbuf_recv(&context.sendbuf, (uint8_t**)&head, NULL, RINGBUF_GET_ALL, 0);
- if ( ret == ESP_OK ) {
+ if (ret == ESP_OK) {
buf_desc_t *desc = head;
- while( desc != NULL ) {
- xQueueSend( context.ret_queue, desc->arg, portMAX_DELAY );
+ while(desc != NULL) {
+ xQueueSend(context.ret_queue, desc->arg, portMAX_DELAY);
last = desc;
desc = STAILQ_NEXT(desc, qe);
}
- sdio_ringbuf_return( &context.sendbuf, (uint8_t*)head );
+ sdio_ringbuf_return(&context.sendbuf, (uint8_t*)head);
}
// if in wait to send state, set the sequence number of tail to the value last sent, just as if the packet wait to
// send never queued.
// Go to idle state (cur_end!=NULL and cur_start=NULL)
- send_set_state( STATE_IDLE );
+ send_set_state(STATE_IDLE);
- if ( last == NULL ) last = (buf_desc_t*)sdio_ringbuf_peek_rear(&context.sendbuf);
+ if (last == NULL) last = (buf_desc_t*)sdio_ringbuf_peek_rear(&context.sendbuf);
last->pkt_len = send_length_read();
return ESP_OK;
}
@@ -1020,15 +1000,15 @@ static esp_err_t send_flush_data()
//clear counter but keep data
static esp_err_t send_reset_counter()
{
- SDIO_SLAVE_CHECK( send_get_state() == STATE_IDLE,
- "reset counter when transmission started", ESP_ERR_INVALID_STATE );
+ SDIO_SLAVE_CHECK(send_get_state() == STATE_IDLE,
+ "reset counter when transmission started", ESP_ERR_INVALID_STATE);
- send_length_write( 0 );
+ send_length_write(0);
uint32_t last_cnt=0;
buf_desc_t *desc = context.in_flight;
buf_desc_t *last = NULL;
- while( desc != NULL ) {
+ while(desc != NULL) {
last_cnt += desc->length;
desc->pkt_len = last_cnt;
last = desc;
@@ -1037,13 +1017,13 @@ static esp_err_t send_reset_counter()
// in theory the desc should be the one right next to the last of in_flight,
// but the link of last is NULL, so get the desc from the ringbuf directly.
desc = (buf_desc_t*)sdio_ringbuf_peek_front(&context.sendbuf);
- while( desc != NULL ) {
+ while(desc != NULL) {
last_cnt += desc->length;
desc->pkt_len = last_cnt;
last = desc;
desc = STAILQ_NEXT(desc, qe);
}
- if ( last == NULL ) {
+ if (last == NULL) {
last = (buf_desc_t*)sdio_ringbuf_peek_rear(&context.sendbuf);
last->pkt_len = 0;
}
@@ -1057,36 +1037,36 @@ static esp_err_t send_reset_counter()
*--------------------------------------------------------------------------*/
//strange but the registers for host->slave transfers are really called "tx*".
-#define CHECK_HANDLE_IDLE(desc) do { if ( desc == NULL || !desc->not_receiving ) {\
+#define CHECK_HANDLE_IDLE(desc) do { if (desc == NULL || !desc->not_receiving) {\
return ESP_ERR_INVALID_ARG; } } while(0)
static inline void critical_enter_recv()
{
- portENTER_CRITICAL( &context.recv_spinlock );
+ portENTER_CRITICAL(&context.recv_spinlock);
}
static inline void critical_exit_recv()
{
- portEXIT_CRITICAL( &context.recv_spinlock );
+ portEXIT_CRITICAL(&context.recv_spinlock);
}
static inline void recv_size_inc()
{
// fields wdata and inc_more should be written by the same instruction.
- SLC.slc0_token1.val = FIELD_TO_VALUE2( SLC_SLC0_TOKEN1_WDATA, 1) | FIELD_TO_VALUE2( SLC_SLC0_TOKEN1_INC_MORE, 1 );
+ SLC.slc0_token1.val = FIELD_TO_VALUE2(SLC_SLC0_TOKEN1_WDATA, 1) | FIELD_TO_VALUE2(SLC_SLC0_TOKEN1_INC_MORE, 1);
}
static inline void recv_size_reset()
{
- SLC.slc0_token1.val = FIELD_TO_VALUE2( SLC_SLC0_TOKEN1_WDATA, 0) | FIELD_TO_VALUE2( SLC_SLC0_TOKEN1_WR, 1 );
+ SLC.slc0_token1.val = FIELD_TO_VALUE2(SLC_SLC0_TOKEN1_WDATA, 0) | FIELD_TO_VALUE2(SLC_SLC0_TOKEN1_WR, 1);
}
static inline buf_desc_t* recv_get_first_empty_buf()
{
buf_stailq_t *const queue = &context.recv_link_list;
buf_desc_t *desc = STAILQ_FIRST(queue);
- while( desc && desc->owner == 0 ) {
- desc = STAILQ_NEXT( desc, qe );
+ while(desc && desc->owner == 0) {
+ desc = STAILQ_NEXT(desc, qe);
}
return desc;
}
@@ -1098,7 +1078,7 @@ static esp_err_t recv_start()
critical_enter_recv();
buf_desc_t *desc = recv_get_first_empty_buf();
- if ( !desc ) {
+ if (!desc) {
ESP_LOGD(TAG, "recv: restart without desc");
critical_exit_recv();
return ESP_OK; // if no buffer loaded, return directly.
@@ -1125,10 +1105,10 @@ static void recv_reset_counter()
critical_enter_recv();
buf_desc_t *desc = recv_get_first_empty_buf();
- while ( desc != NULL ) {
- assert( desc->owner == 1 );
+ while (desc != NULL) {
+ assert(desc->owner == 1);
recv_size_inc();
- desc = STAILQ_NEXT( desc, qe );
+ desc = STAILQ_NEXT(desc, qe);
}
critical_exit_recv();
}
@@ -1140,14 +1120,14 @@ static void recv_flush_data()
critical_enter_recv();
while(1) {
- portBASE_TYPE ret = xSemaphoreTake( context.recv_event, 0 );
- if ( ret == pdFALSE ) break;
+ portBASE_TYPE ret = xSemaphoreTake(context.recv_event, 0);
+ if (ret == pdFALSE) break;
buf_desc_t *desc = STAILQ_FIRST(queue);
- assert ( desc != NULL && desc->owner == 0 );
+ assert (desc != NULL && desc->owner == 0);
STAILQ_REMOVE_HEAD(queue, qe);
desc->owner = 1;
- STAILQ_INSERT_TAIL( queue, desc, qe );
+ STAILQ_INSERT_TAIL(queue, desc, qe);
recv_size_inc();
//we only add it to the tail here, without start the DMA nor increase buffer num.
}
@@ -1157,43 +1137,50 @@ static void recv_flush_data()
static void sdio_intr_recv(void* arg)
{
portBASE_TYPE yield = 0;
- if ( SLC.slc0_int_raw.tx_done ) {
+ if (SLC.slc0_int_raw.tx_done) {
SLC.slc0_int_clr.tx_done = 1;
- assert( context.recv_cur_ret != NULL );
-
- while ( context.recv_cur_ret && context.recv_cur_ret->owner == 0 ) {
+ while (context.recv_cur_ret && context.recv_cur_ret->owner == 0) {
// This may cause the ``cur_ret`` pointer to be NULL, indicating the list is empty,
// in this case the ``tx_done`` should happen no longer until new desc is appended.
// The app is responsible to place the pointer to the right place again when appending new desc.
- context.recv_cur_ret = STAILQ_NEXT( context.recv_cur_ret, qe );
- ESP_EARLY_LOGV( TAG, "intr_recv: Give");
- xSemaphoreGiveFromISR( context.recv_event, &yield );
+ context.recv_cur_ret = STAILQ_NEXT(context.recv_cur_ret, qe);
+ ESP_EARLY_LOGV(TAG, "intr_recv: Give");
+ xSemaphoreGiveFromISR(context.recv_event, &yield);
};
}
- if ( yield ) portYIELD_FROM_ISR();
+ if (yield) portYIELD_FROM_ISR();
}
esp_err_t sdio_slave_recv_load_buf(sdio_slave_buf_handle_t handle)
{
buf_desc_t *desc = (buf_desc_t*)handle;
- CHECK_HANDLE_IDLE( desc );
+ CHECK_HANDLE_IDLE(desc);
buf_stailq_t *const queue = &context.recv_link_list;
critical_enter_recv();
- TAILQ_REMOVE( &context.recv_reg_list, desc, te );
+ TAILQ_REMOVE(&context.recv_reg_list, desc, te);
desc->owner = 1;
desc->not_receiving = 0; //manually remove the prev link (by set not_receiving=0), to indicate this is in the queue
- // 1. If all desc are returned in the ISR, the pointer is moved to NULL. The pointer is set to the newly appended desc here.
- // 2. If the pointer is move to some not-returned desc (maybe the one appended here), do nothing.
- // The ``cur_ret`` pointer must be checked and set after new desc appended to the list, or the pointer setting may fail.
- STAILQ_INSERT_TAIL( queue, desc, qe );
- if ( context.recv_cur_ret == NULL ) {
+ buf_desc_t *const tail = STAILQ_LAST(queue, buf_desc_s, qe);
+
+ STAILQ_INSERT_TAIL(queue, desc, qe);
+ if (tail == NULL || (tail->owner == 0)) {
+ //in this case we have to set the ret pointer
+ if (tail != NULL) {
+ /* if the owner of the tail is returned to the software, the ISR is
+ * expect to write this pointer to NULL in a short time, wait until
+ * that and set new value for this pointer
+ */
+ while (context.recv_cur_ret != NULL) {}
+ }
+ assert(context.recv_cur_ret == NULL);
context.recv_cur_ret = desc;
}
+ assert(context.recv_cur_ret != NULL);
- if ( desc == STAILQ_FIRST(queue) ) {
+ if (tail == NULL) {
//no one in the ll, start new ll operation.
SLC.slc0_tx_link.addr = (uint32_t)desc;
SLC.slc0_tx_link.start = 1;
@@ -1211,11 +1198,11 @@ esp_err_t sdio_slave_recv_load_buf(sdio_slave_buf_handle_t handle)
sdio_slave_buf_handle_t sdio_slave_recv_register_buf(uint8_t *start)
{
- SDIO_SLAVE_CHECK( esp_ptr_dma_capable(start) && (uint32_t)start%4==0,
+ SDIO_SLAVE_CHECK(esp_ptr_dma_capable(start) && (uint32_t)start%4==0,
"buffer to register should be DMA capable and 32-bit aligned", NULL);
buf_desc_t *desc = (buf_desc_t*)malloc(sizeof(buf_desc_t));
- if ( desc == NULL ) {
- SDIO_SLAVE_LOGE( "cannot allocate lldesc for new buffer" );
+ if (desc == NULL) {
+ SDIO_SLAVE_LOGE("cannot allocate lldesc for new buffer");
return NULL;
}
@@ -1226,16 +1213,16 @@ sdio_slave_buf_handle_t sdio_slave_recv_register_buf(uint8_t *start)
//no length required, eof always=0
};
critical_enter_recv();
- TAILQ_INSERT_TAIL( &context.recv_reg_list, desc, te );
+ TAILQ_INSERT_TAIL(&context.recv_reg_list, desc, te);
critical_exit_recv();
return desc;
}
-esp_err_t sdio_slave_recv(sdio_slave_buf_handle_t* handle_ret, uint8_t **start_o, size_t *len_o, TickType_t wait)
+esp_err_t sdio_slave_recv(sdio_slave_buf_handle_t* handle_ret, uint8_t **out_addr, size_t *out_len, TickType_t wait)
{
- SDIO_SLAVE_CHECK( handle_ret != NULL, "handle address cannot be 0", ESP_ERR_INVALID_ARG);
- portBASE_TYPE ret = xSemaphoreTake( context.recv_event, wait );
- if ( ret == pdFALSE ) return ESP_ERR_TIMEOUT;
+ SDIO_SLAVE_CHECK(handle_ret != NULL, "handle address cannot be 0", ESP_ERR_INVALID_ARG);
+ portBASE_TYPE ret = xSemaphoreTake(context.recv_event, wait);
+ if (ret == pdFALSE) return ESP_ERR_TIMEOUT;
buf_stailq_t *const queue = &context.recv_link_list;
@@ -1243,33 +1230,33 @@ esp_err_t sdio_slave_recv(sdio_slave_buf_handle_t* handle_ret, uint8_t **start_o
//remove from queue, add back to reg list.
buf_desc_t *desc = STAILQ_FIRST(queue);
STAILQ_REMOVE_HEAD(queue, qe);
- TAILQ_INSERT_TAIL( &context.recv_reg_list, desc, te );
+ TAILQ_INSERT_TAIL(&context.recv_reg_list, desc, te);
critical_exit_recv();
- assert( desc != NULL && desc->owner == 0 );
+ assert(desc != NULL && desc->owner == 0);
*handle_ret = (sdio_slave_buf_handle_t)desc;
- if ( start_o ) *start_o = desc->buf;
- if ( len_o ) *len_o = desc->length;
+ if (out_addr) *out_addr = desc->buf;
+ if (out_len) *out_len = desc->length;
return ESP_OK;
}
esp_err_t sdio_slave_recv_unregister_buf(sdio_slave_buf_handle_t handle)
{
buf_desc_t *desc = (buf_desc_t*)handle;
- CHECK_HANDLE_IDLE( desc ); //in the queue, fail.
+ CHECK_HANDLE_IDLE(desc); //in the queue, fail.
critical_enter_recv();
- TAILQ_REMOVE( &context.recv_reg_list, desc, te );
+ TAILQ_REMOVE(&context.recv_reg_list, desc, te);
critical_exit_recv();
free(desc);
return ESP_OK;
}
-uint8_t* sdio_slave_recv_get_buf( sdio_slave_buf_handle_t handle, size_t *len_o )
+uint8_t* sdio_slave_recv_get_buf(sdio_slave_buf_handle_t handle, size_t *len_o)
{
buf_desc_t *desc = (buf_desc_t*)handle;
- if ( handle == NULL ) return NULL;
+ if (handle == NULL) return NULL;
- if ( len_o!= NULL ) *len_o= desc->length;
+ if (len_o!= NULL) *len_o= desc->length;
return desc->buf;
}
diff --git a/components/driver/sdmmc_host.c b/components/driver/sdmmc_host.c
index 95cb81fdcf..2534ee5d54 100644
--- a/components/driver/sdmmc_host.c
+++ b/components/driver/sdmmc_host.c
@@ -17,76 +17,21 @@
#include
#include "esp_log.h"
#include "esp_intr_alloc.h"
-#include "soc/sdmmc_struct.h"
-#include "soc/sdmmc_reg.h"
#include "soc/io_mux_reg.h"
-#include "soc/gpio_sig_map.h"
#include "rom/gpio.h"
#include "driver/gpio.h"
#include "driver/sdmmc_host.h"
#include "driver/periph_ctrl.h"
#include "sdmmc_private.h"
#include "freertos/semphr.h"
+#include "soc/sdmmc_periph.h"
#define SDMMC_EVENT_QUEUE_LENGTH 32
-typedef struct {
- uint32_t clk;
- uint32_t cmd;
- uint32_t d0;
- uint32_t d1;
- uint32_t d2;
- uint32_t d3;
- uint32_t d4;
- uint32_t d5;
- uint32_t d6;
- uint32_t d7;
- uint8_t d1_gpio;
- uint8_t d3_gpio;
- uint8_t card_detect;
- uint8_t write_protect;
- uint8_t card_int;
- uint8_t width;
-} sdmmc_slot_info_t;
-
static void sdmmc_isr(void* arg);
static void sdmmc_host_dma_init();
-static const sdmmc_slot_info_t s_slot_info[2] = {
- {
- .clk = PERIPHS_IO_MUX_SD_CLK_U,
- .cmd = PERIPHS_IO_MUX_SD_CMD_U,
- .d0 = PERIPHS_IO_MUX_SD_DATA0_U,
- .d1 = PERIPHS_IO_MUX_SD_DATA1_U,
- .d2 = PERIPHS_IO_MUX_SD_DATA2_U,
- .d3 = PERIPHS_IO_MUX_SD_DATA3_U,
- .d1_gpio = 8,
- .d3_gpio = 10,
- .d4 = PERIPHS_IO_MUX_GPIO16_U,
- .d5 = PERIPHS_IO_MUX_GPIO17_U,
- .d6 = PERIPHS_IO_MUX_GPIO5_U,
- .d7 = PERIPHS_IO_MUX_GPIO18_U,
- .card_detect = HOST_CARD_DETECT_N_1_IDX,
- .write_protect = HOST_CARD_WRITE_PRT_1_IDX,
- .card_int = HOST_CARD_INT_N_1_IDX,
- .width = 8
- },
- {
- .clk = PERIPHS_IO_MUX_MTMS_U,
- .cmd = PERIPHS_IO_MUX_MTDO_U,
- .d0 = PERIPHS_IO_MUX_GPIO2_U,
- .d1 = PERIPHS_IO_MUX_GPIO4_U,
- .d2 = PERIPHS_IO_MUX_MTDI_U,
- .d3 = PERIPHS_IO_MUX_MTCK_U,
- .d1_gpio = 4,
- .d3_gpio = 13,
- .card_detect = HOST_CARD_DETECT_N_2_IDX,
- .write_protect = HOST_CARD_WRITE_PRT_2_IDX,
- .card_int = HOST_CARD_INT_N_2_IDX,
- .width = 4
- }
-};
static const char* TAG = "sdmmc_periph";
static intr_handle_t s_intr_handle;
@@ -340,18 +285,26 @@ esp_err_t sdmmc_host_init()
return ESP_OK;
}
-
-static inline void configure_pin(uint32_t io_mux_reg)
+static void configure_pin(int pin)
{
const int sdmmc_func = 3;
const int drive_strength = 3;
- PIN_INPUT_ENABLE(io_mux_reg);
- PIN_FUNC_SELECT(io_mux_reg, sdmmc_func);
- PIN_SET_DRV(io_mux_reg, drive_strength);
+ assert(pin!=-1);
+ gpio_pulldown_dis(pin);
+
+ uint32_t reg = GPIO_PIN_MUX_REG[pin];
+ assert(reg != UINT32_MAX);
+ PIN_INPUT_ENABLE(reg);
+ PIN_FUNC_SELECT(reg, sdmmc_func);
+ PIN_SET_DRV(reg, drive_strength);
}
esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config)
{
+ bool pullup = slot_config->flags & SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
+ if (pullup) {
+ sdmmc_host_pullup_en(slot, slot_config->width);
+ }
if (!s_intr_handle) {
return ESP_ERR_INVALID_STATE;
}
@@ -366,7 +319,7 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config)
uint8_t slot_width = slot_config->width;
// Configure pins
- const sdmmc_slot_info_t* pslot = &s_slot_info[slot];
+ const sdmmc_slot_info_t* pslot = &sdmmc_slot_info[slot];
if (slot_width == SDMMC_SLOT_WIDTH_DEFAULT) {
slot_width = pslot->width;
@@ -376,13 +329,13 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config)
}
s_slot_width[slot] = slot_width;
- configure_pin(pslot->clk);
- configure_pin(pslot->cmd);
- configure_pin(pslot->d0);
+ configure_pin(pslot->clk_gpio);
+ configure_pin(pslot->cmd_gpio);
+ configure_pin(pslot->d0_gpio);
if (slot_width >= 4) {
- configure_pin(pslot->d1);
- configure_pin(pslot->d2);
+ configure_pin(pslot->d1_gpio);
+ configure_pin(pslot->d2_gpio);
//force pull-up D3 to make slave detect SD mode. connect to peripheral after width configuration.
gpio_config_t gpio_conf = {
.pin_bit_mask = BIT(pslot->d3_gpio),
@@ -394,10 +347,10 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config)
gpio_config( &gpio_conf );
gpio_set_level( pslot->d3_gpio, 1 );
if (slot_width == 8) {
- configure_pin(pslot->d4);
- configure_pin(pslot->d5);
- configure_pin(pslot->d6);
- configure_pin(pslot->d7);
+ configure_pin(pslot->d4_gpio);
+ configure_pin(pslot->d5_gpio);
+ configure_pin(pslot->d6_gpio);
+ configure_pin(pslot->d7_gpio);
}
}
@@ -482,7 +435,7 @@ esp_err_t sdmmc_host_set_bus_width(int slot, size_t width)
if (!(slot == 0 || slot == 1)) {
return ESP_ERR_INVALID_ARG;
}
- if (s_slot_info[slot].width < width) {
+ if (sdmmc_slot_info[slot].width < width) {
return ESP_ERR_INVALID_ARG;
}
const uint16_t mask = BIT(slot);
@@ -492,10 +445,10 @@ esp_err_t sdmmc_host_set_bus_width(int slot, size_t width)
} else if (width == 4) {
SDMMC.ctype.card_width_8 &= ~mask;
SDMMC.ctype.card_width |= mask;
- configure_pin(s_slot_info[slot].d3); // D3 was set to GPIO high to force slave into SD 1-bit mode, until 4-bit mode is set
+ configure_pin(sdmmc_slot_info[slot].d3_gpio); // D3 was set to GPIO high to force slave into SD 1-bit mode, until 4-bit mode is set
} else if (width == 8){
SDMMC.ctype.card_width_8 |= mask;
- configure_pin(s_slot_info[slot].d3); // D3 was set to GPIO high to force slave into SD 1-bit mode, until 4-bit mode is set
+ configure_pin(sdmmc_slot_info[slot].d3_gpio); // D3 was set to GPIO high to force slave into SD 1-bit mode, until 4-bit mode is set
} else {
return ESP_ERR_INVALID_ARG;
}
@@ -550,7 +503,7 @@ void sdmmc_host_dma_resume()
esp_err_t sdmmc_host_io_int_enable(int slot)
{
- configure_pin(s_slot_info[slot].d1);
+ configure_pin(sdmmc_slot_info[slot].d1_gpio);
return ESP_OK;
}
@@ -566,7 +519,7 @@ esp_err_t sdmmc_host_io_int_wait(int slot, TickType_t timeout_ticks)
SDMMC.intmask.sdio &= ~BIT(slot); /* Disable SDIO interrupt */
SDMMC.rintsts.sdio = BIT(slot);
- if (gpio_get_level(s_slot_info[slot].d1_gpio) == 0) {
+ if (gpio_get_level(sdmmc_slot_info[slot].d1_gpio) == 0) {
return ESP_OK;
}
/* Otherwise, need to wait for an interrupt. Since D1 was high,
@@ -627,3 +580,25 @@ static void sdmmc_isr(void* arg) {
}
}
+esp_err_t sdmmc_host_pullup_en(int slot, int width)
+{
+ if (width > sdmmc_slot_info[slot].width) {
+ //in esp32 we only support 8 bit in slot 0, note this is occupied by the flash by default
+ return ESP_ERR_INVALID_ARG;
+ }
+ //according to the spec, the host control the clk, we don't to pull it up here
+ gpio_pullup_en(sdmmc_slot_info[slot].cmd_gpio);
+ gpio_pullup_en(sdmmc_slot_info[slot].d0_gpio);
+ if (width >= 4) {
+ gpio_pullup_en(sdmmc_slot_info[slot].d1_gpio);
+ gpio_pullup_en(sdmmc_slot_info[slot].d2_gpio);
+ gpio_pullup_en(sdmmc_slot_info[slot].d3_gpio);
+ }
+ if (width == 8) {
+ gpio_pullup_en(sdmmc_slot_info[slot].d4_gpio);
+ gpio_pullup_en(sdmmc_slot_info[slot].d5_gpio);
+ gpio_pullup_en(sdmmc_slot_info[slot].d6_gpio);
+ gpio_pullup_en(sdmmc_slot_info[slot].d7_gpio);
+ }
+ return ESP_OK;
+}
\ No newline at end of file
diff --git a/components/driver/sdmmc_private.h b/components/driver/sdmmc_private.h
index 5a10a3b672..8f0aab78b2 100644
--- a/components/driver/sdmmc_private.h
+++ b/components/driver/sdmmc_private.h
@@ -19,7 +19,7 @@
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
-#include "soc/sdmmc_struct.h"
+#include "soc/sdmmc_periph.h"
typedef struct {
uint32_t sdmmc_status; ///< masked SDMMC interrupt status
diff --git a/components/driver/sdmmc_transaction.c b/components/driver/sdmmc_transaction.c
index 8abf9bb923..43f74c0863 100644
--- a/components/driver/sdmmc_transaction.c
+++ b/components/driver/sdmmc_transaction.c
@@ -19,8 +19,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
-#include "soc/sdmmc_reg.h"
-#include "soc/sdmmc_struct.h"
+#include "soc/sdmmc_periph.h"
#include "soc/soc_memory_layout.h"
#include "driver/sdmmc_types.h"
#include "driver/sdmmc_defs.h"
@@ -272,6 +271,16 @@ static esp_err_t handle_event(sdmmc_command_t* cmd, sdmmc_req_state_t* state,
return ESP_OK;
}
+static bool cmd_needs_auto_stop(const sdmmc_command_t* cmd)
+{
+ /* SDMMC host needs an "auto stop" flag for the following commands: */
+ return cmd->datalen > 0 &&
+ (cmd->opcode == MMC_WRITE_BLOCK_MULTIPLE ||
+ cmd->opcode == MMC_READ_BLOCK_MULTIPLE ||
+ cmd->opcode == MMC_WRITE_DAT_UNTIL_STOP ||
+ cmd->opcode == MMC_READ_DAT_UNTIL_STOP);
+}
+
static sdmmc_hw_cmd_t make_hw_cmd(sdmmc_command_t* cmd)
{
sdmmc_hw_cmd_t res = { 0 };
@@ -303,12 +312,11 @@ static sdmmc_hw_cmd_t make_hw_cmd(sdmmc_command_t* cmd)
res.rw = 1;
}
assert(cmd->datalen % cmd->blklen == 0);
- if ((cmd->datalen / cmd->blklen) > 1) {
- res.send_auto_stop = 1;
- }
+ res.send_auto_stop = cmd_needs_auto_stop(cmd) ? 1 : 0;
}
- ESP_LOGV(TAG, "%s: opcode=%d, rexp=%d, crc=%d", __func__,
- res.cmd_index, res.response_expect, res.check_response_crc);
+ ESP_LOGV(TAG, "%s: opcode=%d, rexp=%d, crc=%d, auto_stop=%d", __func__,
+ res.cmd_index, res.response_expect, res.check_response_crc,
+ res.send_auto_stop);
return res;
}
diff --git a/components/driver/sdspi_crc.c b/components/driver/sdspi_crc.c
index 4b47446596..177f1b05b6 100644
--- a/components/driver/sdspi_crc.c
+++ b/components/driver/sdspi_crc.c
@@ -1,53 +1,53 @@
-// Copyright 2015-2017 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.
-
-#include
-#include "rom/crc.h"
-#include "sdspi_crc.h"
-
-static const uint8_t crc7_table[256] =
-{
- 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
- 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
- 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
- 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
- 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
- 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
- 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
- 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
- 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
- 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
- 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
- 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
- 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
- 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
- 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
- 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79,
-};
-
-// returns the CRC-7 for a message of "length" bytes
-uint8_t sdspi_crc7(const uint8_t *data, size_t size)
-{
- uint8_t result = 0;
- for (size_t i = 0; i < size; ++i) {
- result = crc7_table[(result << 1) ^ data[i]];
- }
- return result;
-}
-
-/// Return CRC16 of data, in the on-the-wire format used by SD protocol
-uint16_t sdspi_crc16(const uint8_t* data, size_t size)
-{
- return __builtin_bswap16(crc16_be(UINT16_MAX, data, size) ^ UINT16_MAX);
-}
+// Copyright 2015-2017 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.
+
+#include
+#include "rom/crc.h"
+#include "sdspi_crc.h"
+
+static const uint8_t crc7_table[256] =
+{
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
+ 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
+ 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
+ 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
+ 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
+ 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
+ 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
+ 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
+ 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
+ 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
+ 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
+ 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
+ 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
+ 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
+ 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
+ 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79,
+};
+
+// returns the CRC-7 for a message of "length" bytes
+uint8_t sdspi_crc7(const uint8_t *data, size_t size)
+{
+ uint8_t result = 0;
+ for (size_t i = 0; i < size; ++i) {
+ result = crc7_table[(result << 1) ^ data[i]];
+ }
+ return result;
+}
+
+/// Return CRC16 of data, in the on-the-wire format used by SD protocol
+uint16_t sdspi_crc16(const uint8_t* data, size_t size)
+{
+ return __builtin_bswap16(crc16_be(UINT16_MAX, data, size) ^ UINT16_MAX);
+}
diff --git a/components/driver/sdspi_crc.h b/components/driver/sdspi_crc.h
index 775d682bd3..3bd6e075a3 100644
--- a/components/driver/sdspi_crc.h
+++ b/components/driver/sdspi_crc.h
@@ -1,43 +1,43 @@
-// Copyright 2015-2017 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.
-#pragma once
-#include
-#include
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-
-/**
- * @brief Return CRC7 of data, in the format used by SD protocol
- * @param data array of data used to compute CRC
- * @param size size of data in bytes
- * @return CRC7 value
- */
-uint8_t sdspi_crc7(const uint8_t *data, size_t size);
-
-/**
- * @brief Return CRC16 of data, in the format used by SD protocol
- * @param data array of data used to compute CRC
- * @param size size of data in bytes
- * @return CRC16 value
- */
-uint16_t sdspi_crc16(const uint8_t* data, size_t size);
-
-
-#ifdef __cplusplus
-}
-#endif
+// Copyright 2015-2017 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.
+#pragma once
+#include
+#include
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/**
+ * @brief Return CRC7 of data, in the format used by SD protocol
+ * @param data array of data used to compute CRC
+ * @param size size of data in bytes
+ * @return CRC7 value
+ */
+uint8_t sdspi_crc7(const uint8_t *data, size_t size);
+
+/**
+ * @brief Return CRC16 of data, in the format used by SD protocol
+ * @param data array of data used to compute CRC
+ * @param size size of data in bytes
+ * @return CRC16 value
+ */
+uint16_t sdspi_crc16(const uint8_t* data, size_t size);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/components/driver/sdspi_host.c b/components/driver/sdspi_host.c
index ab9420eb12..e823ee7fa2 100644
--- a/components/driver/sdspi_host.c
+++ b/components/driver/sdspi_host.c
@@ -1,887 +1,887 @@
-// Copyright 2015-2017 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.
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include "esp_log.h"
-#include "esp_heap_caps.h"
-#include "driver/gpio.h"
-#include "driver/sdmmc_defs.h"
-#include "driver/sdspi_host.h"
-#include "sdspi_private.h"
-#include "sdspi_crc.h"
-#include "esp_timer.h"
-
-
-/// Max number of transactions in flight (used in start_command_write_blocks)
-#define SDSPI_TRANSACTION_COUNT 4
-#define SDSPI_MOSI_IDLE_VAL 0xff //!< Data value which causes MOSI to stay high
-#define GPIO_UNUSED 0xff //!< Flag indicating that CD/WP is unused
-/// Size of the buffer returned by get_block_buf
-#define SDSPI_BLOCK_BUF_SIZE (SDSPI_MAX_DATA_LEN + 4)
-/// Maximum number of dummy bytes between the request and response (minimum is 1)
-#define SDSPI_RESPONSE_MAX_DELAY 8
-
-
-/// Structure containing run time configuration for a single SD slot
-typedef struct {
- spi_device_handle_t handle; //!< SPI device handle, used for transactions
- uint8_t gpio_cs; //!< CS GPIO
- uint8_t gpio_cd; //!< Card detect GPIO, or GPIO_UNUSED
- uint8_t gpio_wp; //!< Write protect GPIO, or GPIO_UNUSED
- /// Set to 1 if the higher layer has asked the card to enable CRC checks
- uint8_t data_crc_enabled : 1;
- /// Number of transactions in 'transactions' array which are in use
- uint8_t used_transaction_count: 3;
- /// Intermediate buffer used when application buffer is not in DMA memory;
- /// allocated on demand, SDSPI_BLOCK_BUF_SIZE bytes long. May be zero.
- uint8_t* block_buf;
- /// array with SDSPI_TRANSACTION_COUNT transaction structures
- spi_transaction_t* transactions;
-} slot_info_t;
-
-static slot_info_t s_slots[3];
-static const char *TAG = "sdspi_host";
-
-/// Functions to send out different kinds of commands
-static esp_err_t start_command_read_blocks(int slot, sdspi_hw_cmd_t *cmd,
- uint8_t *data, uint32_t rx_length);
-
-static esp_err_t start_command_write_blocks(int slot, sdspi_hw_cmd_t *cmd,
- const uint8_t *data, uint32_t tx_length);
-
-static esp_err_t start_command_default(int slot, int flags, sdspi_hw_cmd_t *cmd);
-
-static esp_err_t poll_cmd_response(int slot, sdspi_hw_cmd_t *cmd);
-
-/// A few helper functions
-
-/// Set CS high for given slot
-static void cs_high(int slot)
-{
- gpio_set_level(s_slots[slot].gpio_cs, 1);
-}
-
-/// Set CS low for given slot
-static void cs_low(int slot)
-{
- gpio_set_level(s_slots[slot].gpio_cs, 0);
-}
-
-/// Return true if WP pin is configured and is low
-static bool card_write_protected(int slot)
-{
- if (s_slots[slot].gpio_wp == GPIO_UNUSED) {
- return false;
- }
- return gpio_get_level(s_slots[slot].gpio_wp) == 0;
-}
-
-/// Return true if CD pin is configured and is high
-static bool card_missing(int slot)
-{
- if (s_slots[slot].gpio_cd == GPIO_UNUSED) {
- return false;
- }
- return gpio_get_level(s_slots[slot].gpio_cd) == 1;
-}
-
-/// Check if slot number is within bounds
-static bool is_valid_slot(int slot)
-{
- return slot == VSPI_HOST || slot == HSPI_HOST;
-}
-
-static spi_device_handle_t spi_handle(int slot)
-{
- return s_slots[slot].handle;
-}
-
-static bool is_slot_initialized(int slot)
-{
- return spi_handle(slot) != NULL;
-}
-
-static bool data_crc_enabled(int slot)
-{
- return s_slots[slot].data_crc_enabled;
-}
-
-/// Get pointer to a block of DMA memory, allocate if necessary.
-/// This is used if the application provided buffer is not in DMA capable memory.
-static esp_err_t get_block_buf(int slot, uint8_t** out_buf)
-{
- if (s_slots[slot].block_buf == NULL) {
- s_slots[slot].block_buf = heap_caps_malloc(SDSPI_BLOCK_BUF_SIZE, MALLOC_CAP_DMA);
- if (s_slots[slot].block_buf == NULL) {
- return ESP_ERR_NO_MEM;
- }
- }
- *out_buf = s_slots[slot].block_buf;
- return ESP_OK;
-}
-
-static spi_transaction_t* get_transaction(int slot)
-{
- size_t used_transaction_count = s_slots[slot].used_transaction_count;
- assert(used_transaction_count < SDSPI_TRANSACTION_COUNT);
- spi_transaction_t* ret = &s_slots[slot].transactions[used_transaction_count];
- ++s_slots[slot].used_transaction_count;
- return ret;
-}
-
-static void release_transaction(int slot)
-{
- --s_slots[slot].used_transaction_count;
-}
-
-static void wait_for_transactions(int slot)
-{
- size_t used_transaction_count = s_slots[slot].used_transaction_count;
- for (size_t i = 0; i < used_transaction_count; ++i) {
- spi_transaction_t* t_out;
- spi_device_get_trans_result(spi_handle(slot), &t_out, portMAX_DELAY);
- release_transaction(slot);
- }
-}
-
-/// Clock out one byte (CS has to be high) to make the card release MISO
-/// (clocking one bit would work as well, but that triggers a bug in SPI DMA)
-static void release_bus(int slot)
-{
- spi_transaction_t t = {
- .flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA,
- .length = 8,
- .tx_data = {0xff}
- };
- spi_device_transmit(spi_handle(slot), &t);
- // don't care if this failed
-}
-
-/// Clock out 80 cycles (10 bytes) before GO_IDLE command
-static void go_idle_clockout(int slot)
-{
- //actually we need 10, declare 12 to meet requirement of RXDMA
- uint8_t data[12];
- memset(data, 0xff, sizeof(data));
- spi_transaction_t t = {
- .length = 10*8,
- .tx_buffer = data,
- .rx_buffer = data,
- };
- spi_device_transmit(spi_handle(slot), &t);
- // don't care if this failed
-}
-
-
-/// Return true if the pointer can be used for DMA
-static bool ptr_dma_compatible(const void* ptr)
-{
- return (uintptr_t) ptr >= 0x3FFAE000 &&
- (uintptr_t) ptr < 0x40000000;
-}
-
-/**
- * Initialize SPI device. Used to change clock speed.
- * @param slot SPI host number
- * @param clock_speed_hz clock speed, Hz
- * @return ESP_OK on success
- */
-static esp_err_t init_spi_dev(int slot, int clock_speed_hz)
-{
- if (spi_handle(slot)) {
- // Reinitializing
- spi_bus_remove_device(spi_handle(slot));
- s_slots[slot].handle = NULL;
- }
- spi_device_interface_config_t devcfg = {
- .clock_speed_hz = clock_speed_hz,
- .mode = 0,
- // For SD cards, CS must stay low during the whole read/write operation,
- // rather than a single SPI transaction.
- .spics_io_num = -1,
- .queue_size = SDSPI_TRANSACTION_COUNT,
- };
- return spi_bus_add_device((spi_host_device_t) slot, &devcfg, &s_slots[slot].handle);
-}
-
-esp_err_t sdspi_host_init()
-{
- return ESP_OK;
-}
-
-esp_err_t sdspi_host_deinit()
-{
- for (size_t i = 0; i < sizeof(s_slots)/sizeof(s_slots[0]); ++i) {
- if (s_slots[i].handle) {
- spi_bus_remove_device(s_slots[i].handle);
- free(s_slots[i].block_buf);
- s_slots[i].block_buf = NULL;
- free(s_slots[i].transactions);
- s_slots[i].transactions = NULL;
- spi_bus_free((spi_host_device_t) i);
- s_slots[i].handle = NULL;
- }
- }
- return ESP_OK;
-}
-
-esp_err_t sdspi_host_set_card_clk(int slot, uint32_t freq_khz)
-{
- if (!is_valid_slot(slot)) {
- return ESP_ERR_INVALID_ARG;
- }
- if (!is_slot_initialized(slot)) {
- return ESP_ERR_INVALID_STATE;
- }
- ESP_LOGD(TAG, "Setting card clock to %d kHz", freq_khz);
- return init_spi_dev(slot, freq_khz * 1000);
-}
-
-esp_err_t sdspi_host_init_slot(int slot, const sdspi_slot_config_t* slot_config)
-{
- ESP_LOGD(TAG, "%s: SPI%d miso=%d mosi=%d sck=%d cs=%d cd=%d wp=%d, dma_ch=%d",
- __func__, slot + 1,
- slot_config->gpio_miso, slot_config->gpio_mosi,
- slot_config->gpio_sck, slot_config->gpio_cs,
- slot_config->gpio_cd, slot_config->gpio_wp,
- slot_config->dma_channel);
-
- spi_host_device_t host = (spi_host_device_t) slot;
- if (!is_valid_slot(slot)) {
- return ESP_ERR_INVALID_ARG;
- }
-
- spi_bus_config_t buscfg = {
- .miso_io_num = slot_config->gpio_miso,
- .mosi_io_num = slot_config->gpio_mosi,
- .sclk_io_num = slot_config->gpio_sck,
- .quadwp_io_num = -1,
- .quadhd_io_num = -1
- };
-
- // Initialize SPI bus
- esp_err_t ret = spi_bus_initialize((spi_host_device_t)slot, &buscfg,
- slot_config->dma_channel);
- if (ret != ESP_OK) {
- ESP_LOGD(TAG, "spi_bus_initialize failed with rc=0x%x", ret);
- return ret;
- }
-
- // Attach the SD card to the SPI bus
- ret = init_spi_dev(slot, SDMMC_FREQ_PROBING * 1000);
- if (ret != ESP_OK) {
- ESP_LOGD(TAG, "spi_bus_add_device failed with rc=0x%x", ret);
- spi_bus_free(host);
- return ret;
- }
-
- // Configure CS pin
- s_slots[slot].gpio_cs = (uint8_t) slot_config->gpio_cs;
- gpio_config_t io_conf = {
- .intr_type = GPIO_PIN_INTR_DISABLE,
- .mode = GPIO_MODE_OUTPUT,
- .pin_bit_mask = 1LL << slot_config->gpio_cs,
- };
-
- ret = gpio_config(&io_conf);
- if (ret != ESP_OK) {
- ESP_LOGD(TAG, "gpio_config (CS) failed with rc=0x%x", ret);
- spi_bus_remove_device(spi_handle(slot));
- s_slots[slot].handle = NULL;
- spi_bus_free(host);
- return ret;
- }
- cs_high(slot);
-
- // Configure CD and WP pins
- io_conf = (gpio_config_t) {
- .intr_type = GPIO_PIN_INTR_DISABLE,
- .mode = GPIO_MODE_INPUT,
- .pin_bit_mask = 0,
- .pull_up_en = true
- };
- if (slot_config->gpio_cd != SDSPI_SLOT_NO_CD) {
- io_conf.pin_bit_mask |= (1 << slot_config->gpio_cd);
- s_slots[slot].gpio_cd = slot_config->gpio_cd;
- } else {
- s_slots[slot].gpio_cd = GPIO_UNUSED;
- }
-
- if (slot_config->gpio_wp != SDSPI_SLOT_NO_WP) {
- io_conf.pin_bit_mask |= (1 << slot_config->gpio_wp);
- s_slots[slot].gpio_wp = slot_config->gpio_wp;
- } else {
- s_slots[slot].gpio_wp = GPIO_UNUSED;
- }
-
- if (io_conf.pin_bit_mask != 0) {
- ret = gpio_config(&io_conf);
- if (ret != ESP_OK) {
- ESP_LOGD(TAG, "gpio_config (CD/WP) failed with rc=0x%x", ret);
- spi_bus_remove_device(spi_handle(slot));
- s_slots[slot].handle = NULL;
- spi_bus_free(host);
- return ret;
- }
- }
-
- s_slots[slot].transactions = calloc(SDSPI_TRANSACTION_COUNT, sizeof(spi_transaction_t));
- if (s_slots[slot].transactions == NULL) {
- spi_bus_remove_device(spi_handle(slot));
- s_slots[slot].handle = NULL;
- spi_bus_free(host);
- return ESP_ERR_NO_MEM;
- }
-
- return ESP_OK;
-}
-
-
-esp_err_t sdspi_host_start_command(int slot, sdspi_hw_cmd_t *cmd, void *data,
- uint32_t data_size, int flags)
-{
- if (!is_valid_slot(slot)) {
- return ESP_ERR_INVALID_ARG;
- }
- if (!is_slot_initialized(slot)) {
- return ESP_ERR_INVALID_STATE;
- }
- if (card_missing(slot)) {
- return ESP_ERR_NOT_FOUND;
- }
- // save some parts of cmd, as its contents will be overwritten
- int cmd_index = cmd->cmd_index;
- uint32_t cmd_arg;
- memcpy(&cmd_arg, cmd->arguments, sizeof(cmd_arg));
- cmd_arg = __builtin_bswap32(cmd_arg);
- ESP_LOGV(TAG, "%s: slot=%i, CMD%d, arg=0x%08x flags=0x%x, data=%p, data_size=%i crc=0x%02x",
- __func__, slot, cmd_index, cmd_arg, flags, data, data_size, cmd->crc7);
-
-
- // For CMD0, clock out 80 cycles to help the card enter idle state,
- // *before* CS is asserted.
- if (cmd_index == MMC_GO_IDLE_STATE) {
- go_idle_clockout(slot);
- }
- // actual transaction
- esp_err_t ret = ESP_OK;
- cs_low(slot);
- if (flags & SDSPI_CMD_FLAG_DATA) {
- if (flags & SDSPI_CMD_FLAG_WRITE) {
- ret = start_command_write_blocks(slot, cmd, data, data_size);
- } else {
- ret = start_command_read_blocks(slot, cmd, data, data_size);
- }
- } else {
- ret = start_command_default(slot, flags, cmd);
- }
- cs_high(slot);
-
- release_bus(slot);
-
- if (ret != ESP_OK) {
- ESP_LOGD(TAG, "%s: cmd=%d error=0x%x", __func__, cmd_index, ret);
- } else {
- // Update internal state when some commands are sent successfully
- if (cmd_index == SD_CRC_ON_OFF) {
- s_slots[slot].data_crc_enabled = (uint8_t) cmd_arg;
- ESP_LOGD(TAG, "data CRC set=%d", s_slots[slot].data_crc_enabled);
- }
- }
- return ret;
-}
-
-static esp_err_t start_command_default(int slot, int flags, sdspi_hw_cmd_t *cmd)
-{
- size_t cmd_size = SDSPI_CMD_R1_SIZE;
- if ((flags & SDSPI_CMD_FLAG_RSP_R1) ||
- (flags & SDSPI_CMD_FLAG_NORSP)) {
- cmd_size = SDSPI_CMD_R1_SIZE;
- } else if (flags & SDSPI_CMD_FLAG_RSP_R2) {
- cmd_size = SDSPI_CMD_R2_SIZE;
- } else if (flags & SDSPI_CMD_FLAG_RSP_R3) {
- cmd_size = SDSPI_CMD_R3_SIZE;
- } else if (flags & SDSPI_CMD_FLAG_RSP_R7) {
- cmd_size = SDSPI_CMD_R7_SIZE;
- }
- spi_transaction_t t = {
- .flags = 0,
- .length = cmd_size * 8,
- .tx_buffer = cmd,
- .rx_buffer = cmd
- };
- esp_err_t ret = spi_device_transmit(spi_handle(slot), &t);
- if (cmd->cmd_index == MMC_STOP_TRANSMISSION) {
- /* response is a stuff byte from previous transfer, ignore it */
- cmd->r1 = 0xff;
- }
- if (ret != ESP_OK) {
- ESP_LOGD(TAG, "%s: spi_device_transmit returned 0x%x", __func__, ret);
- return ret;
- }
- if (flags & SDSPI_CMD_FLAG_NORSP) {
- /* no (correct) response expected from the card, so skip polling loop */
- ESP_LOGV(TAG, "%s: ignoring response byte", __func__);
- cmd->r1 = 0x00;
- }
- ret = poll_cmd_response(slot, cmd);
- if (ret != ESP_OK) {
- ESP_LOGD(TAG, "%s: poll_cmd_response returned 0x%x", __func__, ret);
- return ret;
- }
- return ESP_OK;
-}
-
-// Wait until MISO goes high
-static esp_err_t poll_busy(int slot, spi_transaction_t* t, int timeout_ms)
-{
- uint8_t t_rx;
- *t = (spi_transaction_t) {
- .tx_buffer = &t_rx,
- .flags = SPI_TRANS_USE_RXDATA, //data stored in rx_data
- .length = 8,
- };
- esp_err_t ret;
-
- uint64_t t_end = esp_timer_get_time() + timeout_ms * 1000;
- int nonzero_count = 0;
- do {
- t_rx = SDSPI_MOSI_IDLE_VAL;
- t->rx_data[0] = 0;
- ret = spi_device_transmit(spi_handle(slot), t);
- if (ret != ESP_OK) {
- return ret;
- }
- if (t->rx_data[0] != 0) {
- if (++nonzero_count == 2) {
- return ESP_OK;
- }
- }
- } while(esp_timer_get_time() < t_end);
- ESP_LOGD(TAG, "%s: timeout", __func__);
- return ESP_ERR_TIMEOUT;
-}
-
-// Wait for response token
-static esp_err_t poll_response_token(int slot, spi_transaction_t* t, int timeout_ms)
-{
- uint8_t t_rx;
- *t = (spi_transaction_t) {
- .tx_buffer = &t_rx,
- .flags = SPI_TRANS_USE_RXDATA,
- .length = 8,
- };
- esp_err_t ret;
- uint64_t t_end = esp_timer_get_time() + timeout_ms * 1000;
- do {
- t_rx = SDSPI_MOSI_IDLE_VAL;
- t->rx_data[0] = 0;
- ret = spi_device_transmit(spi_handle(slot), t);
- if (ret != ESP_OK) {
- return ret;
- }
- if ((t->rx_data[0] & TOKEN_RSP_MASK) == TOKEN_RSP_OK) {
- return ESP_OK;
- }
- if ((t->rx_data[0] & TOKEN_RSP_MASK) == TOKEN_RSP_CRC_ERR) {
- return ESP_ERR_INVALID_CRC;
- }
- if ((t->rx_data[0] & TOKEN_RSP_MASK) == TOKEN_RSP_WRITE_ERR) {
- return ESP_ERR_INVALID_RESPONSE;
- }
- } while (esp_timer_get_time() < t_end);
-
- ESP_LOGD(TAG, "%s: timeout", __func__);
- return ESP_ERR_TIMEOUT;
-}
-
-// Wait for data token, reading 8 bytes at a time.
-// If the token is found, write all subsequent bytes to extra_ptr,
-// and store the number of bytes written to extra_size.
-static esp_err_t poll_data_token(int slot, spi_transaction_t* t,
- uint8_t* extra_ptr, size_t* extra_size, int timeout_ms)
-{
- uint8_t t_rx[8];
- *t = (spi_transaction_t) {
- .tx_buffer = &t_rx,
- .rx_buffer = &t_rx,
- .length = sizeof(t_rx) * 8,
- };
- esp_err_t ret;
- uint64_t t_end = esp_timer_get_time() + timeout_ms * 1000;
- do {
- memset(t_rx, SDSPI_MOSI_IDLE_VAL, sizeof(t_rx));
- ret = spi_device_transmit(spi_handle(slot), t);
- if (ret != ESP_OK) {
- return ret;
- }
- bool found = false;
- for (int byte_idx = 0; byte_idx < sizeof(t_rx); byte_idx++) {
- uint8_t rd_data = t_rx[byte_idx];
- if (rd_data == TOKEN_BLOCK_START) {
- found = true;
- memcpy(extra_ptr, t_rx + byte_idx + 1, sizeof(t_rx) - byte_idx - 1);
- *extra_size = sizeof(t_rx) - byte_idx - 1;
- break;
- }
- if (rd_data != 0xff && rd_data != 0) {
- ESP_LOGD(TAG, "%s: received 0x%02x while waiting for data",
- __func__, rd_data);
- return ESP_ERR_INVALID_RESPONSE;
- }
- }
- if (found) {
- return ESP_OK;
- }
- } while (esp_timer_get_time() < t_end);
- ESP_LOGD(TAG, "%s: timeout", __func__);
- return ESP_ERR_TIMEOUT;
-}
-
-static esp_err_t poll_cmd_response(int slot, sdspi_hw_cmd_t *cmd)
-{
- int response_delay_bytes = SDSPI_RESPONSE_MAX_DELAY;
- while ((cmd->r1 & SD_SPI_R1_NO_RESPONSE) != 0 && response_delay_bytes-- > 0) {
- spi_transaction_t* t = get_transaction(slot);
- *t = (spi_transaction_t) {
- .flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA,
- .length = 8,
- };
- t->tx_data[0] = 0xff;
- esp_err_t ret = spi_device_transmit(spi_handle(slot), t);
- uint8_t r1 = t->rx_data[0];
- release_transaction(slot);
- if (ret != ESP_OK) {
- return ret;
- }
- cmd->r1 = r1;
- }
- if (cmd->r1 & SD_SPI_R1_NO_RESPONSE) {
- return ESP_ERR_TIMEOUT;
- }
- return ESP_OK;
-}
-
-
-/**
- * Receiving one or more blocks of data happens as follows:
- * 1. send command + receive r1 response (SDSPI_CMD_R1_SIZE bytes total)
- * 2. keep receiving bytes until TOKEN_BLOCK_START is encountered (this may
- * take a while, depending on card's read speed)
- * 3. receive up to SDSPI_MAX_DATA_LEN = 512 bytes of actual data
- * 4. receive 2 bytes of CRC
- * 5. for multi block transfers, go to step 2
- *
- * These steps can be done separately, but that leads to a less than optimal
- * performance on large transfers because of delays between each step.
- * For example, if steps 3 and 4 are separate SPI transactions queued one after
- * another, there will be ~16 microseconds of dead time between end of step 3
- * and the beginning of step 4. A delay between two blocking SPI transactions
- * in step 2 is even higher (~60 microseconds).
- *
- * To improve read performance the following sequence is adopted:
- * 1. Do the first transfer: command + r1 response + 8 extra bytes.
- * Set pre_scan_data_ptr to point to the 8 extra bytes, and set
- * pre_scan_data_size to 8.
- * 2. Search pre_scan_data_size bytes for TOKEN_BLOCK_START.
- * If found, the rest of the bytes contain part of the actual data.
- * Store pointer to and size of that extra data as extra_data_{ptr,size}.
- * If not found, fall back to polling for TOKEN_BLOCK_START, 8 bytes at a
- * time (in poll_data_token function). Deal with extra data in the same way,
- * by setting extra_data_{ptr,size}.
- * 3. Receive the remaining 512 - extra_data_size bytes, plus 4 extra bytes
- * (i.e. 516 - extra_data_size). Of the 4 extra bytes, first two will capture
- * the CRC value, and the other two will capture 0xff 0xfe sequence
- * indicating the start of the next block. Actual scanning is done by
- * setting pre_scan_data_ptr to point to these last 2 bytes, and setting
- * pre_scan_data_size = 2, then going to step 2 to receive the next block.
- * When the final block is being received, the number of extra bytes is 2
- * (only for CRC), because we don't need to wait for start token of the
- * next block, and some cards are getting confused by these two extra bytes.
- *
- * With this approach the delay between blocks of a multi-block transfer is
- * ~95 microseconds, out of which 35 microseconds are spend doing the CRC check.
- * Further speedup is possible by pipelining transfers and CRC checks, at an
- * expense of one extra temporary buffer.
- */
-static esp_err_t start_command_read_blocks(int slot, sdspi_hw_cmd_t *cmd,
- uint8_t *data, uint32_t rx_length)
-{
- bool need_stop_command = rx_length > SDSPI_MAX_DATA_LEN;
- spi_transaction_t* t_command = get_transaction(slot);
- *t_command = (spi_transaction_t) {
- .length = (SDSPI_CMD_R1_SIZE + SDSPI_RESPONSE_MAX_DELAY) * 8,
- .tx_buffer = cmd,
- .rx_buffer = cmd,
- };
- esp_err_t ret = spi_device_transmit(spi_handle(slot), t_command);
- if (ret != ESP_OK) {
- return ret;
- }
- release_transaction(slot);
-
- uint8_t* cmd_u8 = (uint8_t*) cmd;
- size_t pre_scan_data_size = SDSPI_RESPONSE_MAX_DELAY;
- uint8_t* pre_scan_data_ptr = cmd_u8 + SDSPI_CMD_R1_SIZE;
-
- /* R1 response is delayed by 1-8 bytes from the request.
- * This loop searches for the response and writes it to cmd->r1.
- */
- while ((cmd->r1 & SD_SPI_R1_NO_RESPONSE) != 0 && pre_scan_data_size > 0) {
- cmd->r1 = *pre_scan_data_ptr;
- ++pre_scan_data_ptr;
- --pre_scan_data_size;
- }
- if (cmd->r1 & SD_SPI_R1_NO_RESPONSE) {
- ESP_LOGD(TAG, "no response token found");
- return ESP_ERR_TIMEOUT;
- }
-
- while (rx_length > 0) {
- size_t extra_data_size = 0;
- const uint8_t* extra_data_ptr = NULL;
- bool need_poll = true;
-
- for (int i = 0; i < pre_scan_data_size; ++i) {
- if (pre_scan_data_ptr[i] == TOKEN_BLOCK_START) {
- extra_data_size = pre_scan_data_size - i - 1;
- extra_data_ptr = pre_scan_data_ptr + i + 1;
- need_poll = false;
- break;
- }
- }
-
- if (need_poll) {
- // Wait for data to be ready
- spi_transaction_t* t_poll = get_transaction(slot);
- ret = poll_data_token(slot, t_poll, cmd_u8 + SDSPI_CMD_R1_SIZE, &extra_data_size, cmd->timeout_ms);
- release_transaction(slot);
- if (ret != ESP_OK) {
- return ret;
- }
- if (extra_data_size) {
- extra_data_ptr = cmd_u8 + SDSPI_CMD_R1_SIZE;
- }
- }
-
- // Arrange RX buffer
- size_t will_receive = MIN(rx_length, SDSPI_MAX_DATA_LEN) - extra_data_size;
- uint8_t* rx_data;
- ret = get_block_buf(slot, &rx_data);
- if (ret != ESP_OK) {
- return ret;
- }
-
- // receive actual data
- const size_t receive_extra_bytes = (rx_length > SDSPI_MAX_DATA_LEN) ? 4 : 2;
- memset(rx_data, 0xff, will_receive + receive_extra_bytes);
- spi_transaction_t* t_data = get_transaction(slot);
- *t_data = (spi_transaction_t) {
- .length = (will_receive + receive_extra_bytes) * 8,
- .rx_buffer = rx_data,
- .tx_buffer = rx_data
- };
-
- ret = spi_device_transmit(spi_handle(slot), t_data);
- if (ret != ESP_OK) {
- return ret;
- }
- release_transaction(slot);
-
- // CRC bytes need to be received even if CRC is not enabled
- uint16_t crc = UINT16_MAX;
- memcpy(&crc, rx_data + will_receive, sizeof(crc));
-
- // Bytes to scan for the start token
- pre_scan_data_size = receive_extra_bytes - sizeof(crc);
- pre_scan_data_ptr = rx_data + will_receive + sizeof(crc);
-
- // Copy data to the destination buffer
- memcpy(data + extra_data_size, rx_data, will_receive);
- if (extra_data_size) {
- memcpy(data, extra_data_ptr, extra_data_size);
- }
-
- // compute CRC of the received data
- uint16_t crc_of_data = 0;
- if (data_crc_enabled(slot)) {
- crc_of_data = sdspi_crc16(data, will_receive + extra_data_size);
- if (crc_of_data != crc) {
- ESP_LOGE(TAG, "data CRC failed, got=0x%04x expected=0x%04x", crc_of_data, crc);
- esp_log_buffer_hex(TAG, data, 16);
- return ESP_ERR_INVALID_CRC;
- }
- }
-
- data += will_receive + extra_data_size;
- rx_length -= will_receive + extra_data_size;
- extra_data_size = 0;
- extra_data_ptr = NULL;
- }
-
- if (need_stop_command) {
- // To end multi block transfer, send stop command and wait for the
- // card to process it
- sdspi_hw_cmd_t stop_cmd;
- make_hw_cmd(MMC_STOP_TRANSMISSION, 0, cmd->timeout_ms, &stop_cmd);
- ret = start_command_default(slot, SDSPI_CMD_FLAG_RSP_R1, &stop_cmd);
- if (ret != ESP_OK) {
- return ret;
- }
- if (stop_cmd.r1 != 0) {
- ESP_LOGD(TAG, "%s: STOP_TRANSMISSION response 0x%02x", __func__, stop_cmd.r1);
- }
- spi_transaction_t* t_poll = get_transaction(slot);
- ret = poll_busy(slot, t_poll, cmd->timeout_ms);
- release_transaction(slot);
- if (ret != ESP_OK) {
- return ret;
- }
- }
- return ESP_OK;
-}
-
-static esp_err_t start_command_write_blocks(int slot, sdspi_hw_cmd_t *cmd,
- const uint8_t *data, uint32_t tx_length)
-{
- if (card_write_protected(slot)) {
- ESP_LOGW(TAG, "%s: card write protected", __func__);
- return ESP_ERR_INVALID_STATE;
- }
- spi_transaction_t* t_command = get_transaction(slot);
- *t_command = (spi_transaction_t) {
- .length = SDSPI_CMD_R1_SIZE * 8,
- .tx_buffer = cmd,
- .rx_buffer = cmd,
- };
- esp_err_t ret = spi_device_queue_trans(spi_handle(slot), t_command, 0);
- if (ret != ESP_OK) {
- return ret;
- }
- wait_for_transactions(slot);
-
- // Poll for command response which may be delayed up to 8 bytes
- ret = poll_cmd_response(slot, cmd);
- if (ret != ESP_OK) {
- ESP_LOGD(TAG, "%s: poll_cmd_response returned 0x%x", __func__, ret);
- return ret;
- }
-
- uint8_t start_token = tx_length <= SDSPI_MAX_DATA_LEN ?
- TOKEN_BLOCK_START : TOKEN_BLOCK_START_WRITE_MULTI;
-
- while (tx_length > 0) {
-
- // Write block start token
- spi_transaction_t* t_start_token = get_transaction(slot);
- *t_start_token = (spi_transaction_t) {
- .length = sizeof(start_token) * 8,
- .tx_buffer = &start_token
- };
- ret = spi_device_queue_trans(spi_handle(slot), t_start_token, 0);
- if (ret != ESP_OK) {
- return ret;
- }
-
- // Prepare data to be sent
- size_t will_send = MIN(tx_length, SDSPI_MAX_DATA_LEN);
- const uint8_t* tx_data = data;
- if (!ptr_dma_compatible(tx_data)) {
- // If the pointer can't be used with DMA, copy data into a new buffer
- uint8_t* tmp;
- ret = get_block_buf(slot, &tmp);
- if (ret != ESP_OK) {
- return ret;
- }
- memcpy(tmp, tx_data, will_send);
- tx_data = tmp;
- }
-
- // Write data
- spi_transaction_t* t_data = get_transaction(slot);
- *t_data = (spi_transaction_t) {
- .length = will_send * 8,
- .tx_buffer = tx_data,
- };
- ret = spi_device_queue_trans(spi_handle(slot), t_data, 0);
- if (ret != ESP_OK) {
- return ret;
- }
-
- // Write CRC
- uint16_t crc = sdspi_crc16(data, will_send);
- spi_transaction_t* t_crc = get_transaction(slot);
- *t_crc = (spi_transaction_t) {
- .length = sizeof(crc) * 8,
- .tx_buffer = (uint8_t*) &crc,
- };
- ret = spi_device_queue_trans(spi_handle(slot), t_crc, 0);
- if (ret != ESP_OK) {
- return ret;
- }
-
- // Wait for data to be sent
- wait_for_transactions(slot);
-
- // Poll for response
- spi_transaction_t* t_poll = get_transaction(slot);
- ret = poll_response_token(slot, t_poll, cmd->timeout_ms);
- release_transaction(slot);
- if (ret != ESP_OK) {
- return ret;
- }
-
- // Wait for the card to finish writing data
- t_poll = get_transaction(slot);
- ret = poll_busy(slot, t_poll, cmd->timeout_ms);
- release_transaction(slot);
- if (ret != ESP_OK) {
- return ret;
- }
-
- tx_length -= will_send;
- data += will_send;
- }
-
- if (start_token == TOKEN_BLOCK_START_WRITE_MULTI) {
- uint8_t stop_token[2] = {
- TOKEN_BLOCK_STOP_WRITE_MULTI,
- SDSPI_MOSI_IDLE_VAL
- };
- spi_transaction_t* t_stop_token = get_transaction(slot);
- *t_stop_token = (spi_transaction_t) {
- .length = sizeof(stop_token) * 8,
- .tx_buffer = &stop_token,
- };
- ret = spi_device_queue_trans(spi_handle(slot), t_stop_token, 0);
- if (ret != ESP_OK) {
- return ret;
- }
- wait_for_transactions(slot);
-
- spi_transaction_t* t_poll = get_transaction(slot);
- ret = poll_busy(slot, t_poll, cmd->timeout_ms);
- release_transaction(slot);
- if (ret != ESP_OK) {
- return ret;
- }
- }
-
- return ESP_OK;
-}
+// Copyright 2015-2017 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.
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "esp_log.h"
+#include "esp_heap_caps.h"
+#include "driver/gpio.h"
+#include "driver/sdmmc_defs.h"
+#include "driver/sdspi_host.h"
+#include "sdspi_private.h"
+#include "sdspi_crc.h"
+#include "esp_timer.h"
+
+
+/// Max number of transactions in flight (used in start_command_write_blocks)
+#define SDSPI_TRANSACTION_COUNT 4
+#define SDSPI_MOSI_IDLE_VAL 0xff //!< Data value which causes MOSI to stay high
+#define GPIO_UNUSED 0xff //!< Flag indicating that CD/WP is unused
+/// Size of the buffer returned by get_block_buf
+#define SDSPI_BLOCK_BUF_SIZE (SDSPI_MAX_DATA_LEN + 4)
+/// Maximum number of dummy bytes between the request and response (minimum is 1)
+#define SDSPI_RESPONSE_MAX_DELAY 8
+
+
+/// Structure containing run time configuration for a single SD slot
+typedef struct {
+ spi_device_handle_t handle; //!< SPI device handle, used for transactions
+ uint8_t gpio_cs; //!< CS GPIO
+ uint8_t gpio_cd; //!< Card detect GPIO, or GPIO_UNUSED
+ uint8_t gpio_wp; //!< Write protect GPIO, or GPIO_UNUSED
+ /// Set to 1 if the higher layer has asked the card to enable CRC checks
+ uint8_t data_crc_enabled : 1;
+ /// Number of transactions in 'transactions' array which are in use
+ uint8_t used_transaction_count: 3;
+ /// Intermediate buffer used when application buffer is not in DMA memory;
+ /// allocated on demand, SDSPI_BLOCK_BUF_SIZE bytes long. May be zero.
+ uint8_t* block_buf;
+ /// array with SDSPI_TRANSACTION_COUNT transaction structures
+ spi_transaction_t* transactions;
+} slot_info_t;
+
+static slot_info_t s_slots[3];
+static const char *TAG = "sdspi_host";
+
+/// Functions to send out different kinds of commands
+static esp_err_t start_command_read_blocks(int slot, sdspi_hw_cmd_t *cmd,
+ uint8_t *data, uint32_t rx_length);
+
+static esp_err_t start_command_write_blocks(int slot, sdspi_hw_cmd_t *cmd,
+ const uint8_t *data, uint32_t tx_length);
+
+static esp_err_t start_command_default(int slot, int flags, sdspi_hw_cmd_t *cmd);
+
+static esp_err_t poll_cmd_response(int slot, sdspi_hw_cmd_t *cmd);
+
+/// A few helper functions
+
+/// Set CS high for given slot
+static void cs_high(int slot)
+{
+ gpio_set_level(s_slots[slot].gpio_cs, 1);
+}
+
+/// Set CS low for given slot
+static void cs_low(int slot)
+{
+ gpio_set_level(s_slots[slot].gpio_cs, 0);
+}
+
+/// Return true if WP pin is configured and is low
+static bool card_write_protected(int slot)
+{
+ if (s_slots[slot].gpio_wp == GPIO_UNUSED) {
+ return false;
+ }
+ return gpio_get_level(s_slots[slot].gpio_wp) == 0;
+}
+
+/// Return true if CD pin is configured and is high
+static bool card_missing(int slot)
+{
+ if (s_slots[slot].gpio_cd == GPIO_UNUSED) {
+ return false;
+ }
+ return gpio_get_level(s_slots[slot].gpio_cd) == 1;
+}
+
+/// Check if slot number is within bounds
+static bool is_valid_slot(int slot)
+{
+ return slot == VSPI_HOST || slot == HSPI_HOST;
+}
+
+static spi_device_handle_t spi_handle(int slot)
+{
+ return s_slots[slot].handle;
+}
+
+static bool is_slot_initialized(int slot)
+{
+ return spi_handle(slot) != NULL;
+}
+
+static bool data_crc_enabled(int slot)
+{
+ return s_slots[slot].data_crc_enabled;
+}
+
+/// Get pointer to a block of DMA memory, allocate if necessary.
+/// This is used if the application provided buffer is not in DMA capable memory.
+static esp_err_t get_block_buf(int slot, uint8_t** out_buf)
+{
+ if (s_slots[slot].block_buf == NULL) {
+ s_slots[slot].block_buf = heap_caps_malloc(SDSPI_BLOCK_BUF_SIZE, MALLOC_CAP_DMA);
+ if (s_slots[slot].block_buf == NULL) {
+ return ESP_ERR_NO_MEM;
+ }
+ }
+ *out_buf = s_slots[slot].block_buf;
+ return ESP_OK;
+}
+
+static spi_transaction_t* get_transaction(int slot)
+{
+ size_t used_transaction_count = s_slots[slot].used_transaction_count;
+ assert(used_transaction_count < SDSPI_TRANSACTION_COUNT);
+ spi_transaction_t* ret = &s_slots[slot].transactions[used_transaction_count];
+ ++s_slots[slot].used_transaction_count;
+ return ret;
+}
+
+static void release_transaction(int slot)
+{
+ --s_slots[slot].used_transaction_count;
+}
+
+static void wait_for_transactions(int slot)
+{
+ size_t used_transaction_count = s_slots[slot].used_transaction_count;
+ for (size_t i = 0; i < used_transaction_count; ++i) {
+ spi_transaction_t* t_out;
+ spi_device_get_trans_result(spi_handle(slot), &t_out, portMAX_DELAY);
+ release_transaction(slot);
+ }
+}
+
+/// Clock out one byte (CS has to be high) to make the card release MISO
+/// (clocking one bit would work as well, but that triggers a bug in SPI DMA)
+static void release_bus(int slot)
+{
+ spi_transaction_t t = {
+ .flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA,
+ .length = 8,
+ .tx_data = {0xff}
+ };
+ spi_device_transmit(spi_handle(slot), &t);
+ // don't care if this failed
+}
+
+/// Clock out 80 cycles (10 bytes) before GO_IDLE command
+static void go_idle_clockout(int slot)
+{
+ //actually we need 10, declare 12 to meet requirement of RXDMA
+ uint8_t data[12];
+ memset(data, 0xff, sizeof(data));
+ spi_transaction_t t = {
+ .length = 10*8,
+ .tx_buffer = data,
+ .rx_buffer = data,
+ };
+ spi_device_transmit(spi_handle(slot), &t);
+ // don't care if this failed
+}
+
+
+/// Return true if the pointer can be used for DMA
+static bool ptr_dma_compatible(const void* ptr)
+{
+ return (uintptr_t) ptr >= 0x3FFAE000 &&
+ (uintptr_t) ptr < 0x40000000;
+}
+
+/**
+ * Initialize SPI device. Used to change clock speed.
+ * @param slot SPI host number
+ * @param clock_speed_hz clock speed, Hz
+ * @return ESP_OK on success
+ */
+static esp_err_t init_spi_dev(int slot, int clock_speed_hz)
+{
+ if (spi_handle(slot)) {
+ // Reinitializing
+ spi_bus_remove_device(spi_handle(slot));
+ s_slots[slot].handle = NULL;
+ }
+ spi_device_interface_config_t devcfg = {
+ .clock_speed_hz = clock_speed_hz,
+ .mode = 0,
+ // For SD cards, CS must stay low during the whole read/write operation,
+ // rather than a single SPI transaction.
+ .spics_io_num = -1,
+ .queue_size = SDSPI_TRANSACTION_COUNT,
+ };
+ return spi_bus_add_device((spi_host_device_t) slot, &devcfg, &s_slots[slot].handle);
+}
+
+esp_err_t sdspi_host_init()
+{
+ return ESP_OK;
+}
+
+esp_err_t sdspi_host_deinit()
+{
+ for (size_t i = 0; i < sizeof(s_slots)/sizeof(s_slots[0]); ++i) {
+ if (s_slots[i].handle) {
+ spi_bus_remove_device(s_slots[i].handle);
+ free(s_slots[i].block_buf);
+ s_slots[i].block_buf = NULL;
+ free(s_slots[i].transactions);
+ s_slots[i].transactions = NULL;
+ spi_bus_free((spi_host_device_t) i);
+ s_slots[i].handle = NULL;
+ }
+ }
+ return ESP_OK;
+}
+
+esp_err_t sdspi_host_set_card_clk(int slot, uint32_t freq_khz)
+{
+ if (!is_valid_slot(slot)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+ if (!is_slot_initialized(slot)) {
+ return ESP_ERR_INVALID_STATE;
+ }
+ ESP_LOGD(TAG, "Setting card clock to %d kHz", freq_khz);
+ return init_spi_dev(slot, freq_khz * 1000);
+}
+
+esp_err_t sdspi_host_init_slot(int slot, const sdspi_slot_config_t* slot_config)
+{
+ ESP_LOGD(TAG, "%s: SPI%d miso=%d mosi=%d sck=%d cs=%d cd=%d wp=%d, dma_ch=%d",
+ __func__, slot + 1,
+ slot_config->gpio_miso, slot_config->gpio_mosi,
+ slot_config->gpio_sck, slot_config->gpio_cs,
+ slot_config->gpio_cd, slot_config->gpio_wp,
+ slot_config->dma_channel);
+
+ spi_host_device_t host = (spi_host_device_t) slot;
+ if (!is_valid_slot(slot)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ spi_bus_config_t buscfg = {
+ .miso_io_num = slot_config->gpio_miso,
+ .mosi_io_num = slot_config->gpio_mosi,
+ .sclk_io_num = slot_config->gpio_sck,
+ .quadwp_io_num = -1,
+ .quadhd_io_num = -1
+ };
+
+ // Initialize SPI bus
+ esp_err_t ret = spi_bus_initialize((spi_host_device_t)slot, &buscfg,
+ slot_config->dma_channel);
+ if (ret != ESP_OK) {
+ ESP_LOGD(TAG, "spi_bus_initialize failed with rc=0x%x", ret);
+ return ret;
+ }
+
+ // Attach the SD card to the SPI bus
+ ret = init_spi_dev(slot, SDMMC_FREQ_PROBING * 1000);
+ if (ret != ESP_OK) {
+ ESP_LOGD(TAG, "spi_bus_add_device failed with rc=0x%x", ret);
+ spi_bus_free(host);
+ return ret;
+ }
+
+ // Configure CS pin
+ s_slots[slot].gpio_cs = (uint8_t) slot_config->gpio_cs;
+ gpio_config_t io_conf = {
+ .intr_type = GPIO_PIN_INTR_DISABLE,
+ .mode = GPIO_MODE_OUTPUT,
+ .pin_bit_mask = 1LL << slot_config->gpio_cs,
+ };
+
+ ret = gpio_config(&io_conf);
+ if (ret != ESP_OK) {
+ ESP_LOGD(TAG, "gpio_config (CS) failed with rc=0x%x", ret);
+ spi_bus_remove_device(spi_handle(slot));
+ s_slots[slot].handle = NULL;
+ spi_bus_free(host);
+ return ret;
+ }
+ cs_high(slot);
+
+ // Configure CD and WP pins
+ io_conf = (gpio_config_t) {
+ .intr_type = GPIO_PIN_INTR_DISABLE,
+ .mode = GPIO_MODE_INPUT,
+ .pin_bit_mask = 0,
+ .pull_up_en = true
+ };
+ if (slot_config->gpio_cd != SDSPI_SLOT_NO_CD) {
+ io_conf.pin_bit_mask |= (1 << slot_config->gpio_cd);
+ s_slots[slot].gpio_cd = slot_config->gpio_cd;
+ } else {
+ s_slots[slot].gpio_cd = GPIO_UNUSED;
+ }
+
+ if (slot_config->gpio_wp != SDSPI_SLOT_NO_WP) {
+ io_conf.pin_bit_mask |= (1 << slot_config->gpio_wp);
+ s_slots[slot].gpio_wp = slot_config->gpio_wp;
+ } else {
+ s_slots[slot].gpio_wp = GPIO_UNUSED;
+ }
+
+ if (io_conf.pin_bit_mask != 0) {
+ ret = gpio_config(&io_conf);
+ if (ret != ESP_OK) {
+ ESP_LOGD(TAG, "gpio_config (CD/WP) failed with rc=0x%x", ret);
+ spi_bus_remove_device(spi_handle(slot));
+ s_slots[slot].handle = NULL;
+ spi_bus_free(host);
+ return ret;
+ }
+ }
+
+ s_slots[slot].transactions = calloc(SDSPI_TRANSACTION_COUNT, sizeof(spi_transaction_t));
+ if (s_slots[slot].transactions == NULL) {
+ spi_bus_remove_device(spi_handle(slot));
+ s_slots[slot].handle = NULL;
+ spi_bus_free(host);
+ return ESP_ERR_NO_MEM;
+ }
+
+ return ESP_OK;
+}
+
+
+esp_err_t sdspi_host_start_command(int slot, sdspi_hw_cmd_t *cmd, void *data,
+ uint32_t data_size, int flags)
+{
+ if (!is_valid_slot(slot)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+ if (!is_slot_initialized(slot)) {
+ return ESP_ERR_INVALID_STATE;
+ }
+ if (card_missing(slot)) {
+ return ESP_ERR_NOT_FOUND;
+ }
+ // save some parts of cmd, as its contents will be overwritten
+ int cmd_index = cmd->cmd_index;
+ uint32_t cmd_arg;
+ memcpy(&cmd_arg, cmd->arguments, sizeof(cmd_arg));
+ cmd_arg = __builtin_bswap32(cmd_arg);
+ ESP_LOGV(TAG, "%s: slot=%i, CMD%d, arg=0x%08x flags=0x%x, data=%p, data_size=%i crc=0x%02x",
+ __func__, slot, cmd_index, cmd_arg, flags, data, data_size, cmd->crc7);
+
+
+ // For CMD0, clock out 80 cycles to help the card enter idle state,
+ // *before* CS is asserted.
+ if (cmd_index == MMC_GO_IDLE_STATE) {
+ go_idle_clockout(slot);
+ }
+ // actual transaction
+ esp_err_t ret = ESP_OK;
+ cs_low(slot);
+ if (flags & SDSPI_CMD_FLAG_DATA) {
+ if (flags & SDSPI_CMD_FLAG_WRITE) {
+ ret = start_command_write_blocks(slot, cmd, data, data_size);
+ } else {
+ ret = start_command_read_blocks(slot, cmd, data, data_size);
+ }
+ } else {
+ ret = start_command_default(slot, flags, cmd);
+ }
+ cs_high(slot);
+
+ release_bus(slot);
+
+ if (ret != ESP_OK) {
+ ESP_LOGD(TAG, "%s: cmd=%d error=0x%x", __func__, cmd_index, ret);
+ } else {
+ // Update internal state when some commands are sent successfully
+ if (cmd_index == SD_CRC_ON_OFF) {
+ s_slots[slot].data_crc_enabled = (uint8_t) cmd_arg;
+ ESP_LOGD(TAG, "data CRC set=%d", s_slots[slot].data_crc_enabled);
+ }
+ }
+ return ret;
+}
+
+static esp_err_t start_command_default(int slot, int flags, sdspi_hw_cmd_t *cmd)
+{
+ size_t cmd_size = SDSPI_CMD_R1_SIZE;
+ if ((flags & SDSPI_CMD_FLAG_RSP_R1) ||
+ (flags & SDSPI_CMD_FLAG_NORSP)) {
+ cmd_size = SDSPI_CMD_R1_SIZE;
+ } else if (flags & SDSPI_CMD_FLAG_RSP_R2) {
+ cmd_size = SDSPI_CMD_R2_SIZE;
+ } else if (flags & SDSPI_CMD_FLAG_RSP_R3) {
+ cmd_size = SDSPI_CMD_R3_SIZE;
+ } else if (flags & SDSPI_CMD_FLAG_RSP_R7) {
+ cmd_size = SDSPI_CMD_R7_SIZE;
+ }
+ spi_transaction_t t = {
+ .flags = 0,
+ .length = cmd_size * 8,
+ .tx_buffer = cmd,
+ .rx_buffer = cmd
+ };
+ esp_err_t ret = spi_device_transmit(spi_handle(slot), &t);
+ if (cmd->cmd_index == MMC_STOP_TRANSMISSION) {
+ /* response is a stuff byte from previous transfer, ignore it */
+ cmd->r1 = 0xff;
+ }
+ if (ret != ESP_OK) {
+ ESP_LOGD(TAG, "%s: spi_device_transmit returned 0x%x", __func__, ret);
+ return ret;
+ }
+ if (flags & SDSPI_CMD_FLAG_NORSP) {
+ /* no (correct) response expected from the card, so skip polling loop */
+ ESP_LOGV(TAG, "%s: ignoring response byte", __func__);
+ cmd->r1 = 0x00;
+ }
+ ret = poll_cmd_response(slot, cmd);
+ if (ret != ESP_OK) {
+ ESP_LOGD(TAG, "%s: poll_cmd_response returned 0x%x", __func__, ret);
+ return ret;
+ }
+ return ESP_OK;
+}
+
+// Wait until MISO goes high
+static esp_err_t poll_busy(int slot, spi_transaction_t* t, int timeout_ms)
+{
+ uint8_t t_rx;
+ *t = (spi_transaction_t) {
+ .tx_buffer = &t_rx,
+ .flags = SPI_TRANS_USE_RXDATA, //data stored in rx_data
+ .length = 8,
+ };
+ esp_err_t ret;
+
+ uint64_t t_end = esp_timer_get_time() + timeout_ms * 1000;
+ int nonzero_count = 0;
+ do {
+ t_rx = SDSPI_MOSI_IDLE_VAL;
+ t->rx_data[0] = 0;
+ ret = spi_device_transmit(spi_handle(slot), t);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ if (t->rx_data[0] != 0) {
+ if (++nonzero_count == 2) {
+ return ESP_OK;
+ }
+ }
+ } while(esp_timer_get_time() < t_end);
+ ESP_LOGD(TAG, "%s: timeout", __func__);
+ return ESP_ERR_TIMEOUT;
+}
+
+// Wait for response token
+static esp_err_t poll_response_token(int slot, spi_transaction_t* t, int timeout_ms)
+{
+ uint8_t t_rx;
+ *t = (spi_transaction_t) {
+ .tx_buffer = &t_rx,
+ .flags = SPI_TRANS_USE_RXDATA,
+ .length = 8,
+ };
+ esp_err_t ret;
+ uint64_t t_end = esp_timer_get_time() + timeout_ms * 1000;
+ do {
+ t_rx = SDSPI_MOSI_IDLE_VAL;
+ t->rx_data[0] = 0;
+ ret = spi_device_transmit(spi_handle(slot), t);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ if ((t->rx_data[0] & TOKEN_RSP_MASK) == TOKEN_RSP_OK) {
+ return ESP_OK;
+ }
+ if ((t->rx_data[0] & TOKEN_RSP_MASK) == TOKEN_RSP_CRC_ERR) {
+ return ESP_ERR_INVALID_CRC;
+ }
+ if ((t->rx_data[0] & TOKEN_RSP_MASK) == TOKEN_RSP_WRITE_ERR) {
+ return ESP_ERR_INVALID_RESPONSE;
+ }
+ } while (esp_timer_get_time() < t_end);
+
+ ESP_LOGD(TAG, "%s: timeout", __func__);
+ return ESP_ERR_TIMEOUT;
+}
+
+// Wait for data token, reading 8 bytes at a time.
+// If the token is found, write all subsequent bytes to extra_ptr,
+// and store the number of bytes written to extra_size.
+static esp_err_t poll_data_token(int slot, spi_transaction_t* t,
+ uint8_t* extra_ptr, size_t* extra_size, int timeout_ms)
+{
+ uint8_t t_rx[8];
+ *t = (spi_transaction_t) {
+ .tx_buffer = &t_rx,
+ .rx_buffer = &t_rx,
+ .length = sizeof(t_rx) * 8,
+ };
+ esp_err_t ret;
+ uint64_t t_end = esp_timer_get_time() + timeout_ms * 1000;
+ do {
+ memset(t_rx, SDSPI_MOSI_IDLE_VAL, sizeof(t_rx));
+ ret = spi_device_transmit(spi_handle(slot), t);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ bool found = false;
+ for (int byte_idx = 0; byte_idx < sizeof(t_rx); byte_idx++) {
+ uint8_t rd_data = t_rx[byte_idx];
+ if (rd_data == TOKEN_BLOCK_START) {
+ found = true;
+ memcpy(extra_ptr, t_rx + byte_idx + 1, sizeof(t_rx) - byte_idx - 1);
+ *extra_size = sizeof(t_rx) - byte_idx - 1;
+ break;
+ }
+ if (rd_data != 0xff && rd_data != 0) {
+ ESP_LOGD(TAG, "%s: received 0x%02x while waiting for data",
+ __func__, rd_data);
+ return ESP_ERR_INVALID_RESPONSE;
+ }
+ }
+ if (found) {
+ return ESP_OK;
+ }
+ } while (esp_timer_get_time() < t_end);
+ ESP_LOGD(TAG, "%s: timeout", __func__);
+ return ESP_ERR_TIMEOUT;
+}
+
+static esp_err_t poll_cmd_response(int slot, sdspi_hw_cmd_t *cmd)
+{
+ int response_delay_bytes = SDSPI_RESPONSE_MAX_DELAY;
+ while ((cmd->r1 & SD_SPI_R1_NO_RESPONSE) != 0 && response_delay_bytes-- > 0) {
+ spi_transaction_t* t = get_transaction(slot);
+ *t = (spi_transaction_t) {
+ .flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA,
+ .length = 8,
+ };
+ t->tx_data[0] = 0xff;
+ esp_err_t ret = spi_device_transmit(spi_handle(slot), t);
+ uint8_t r1 = t->rx_data[0];
+ release_transaction(slot);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ cmd->r1 = r1;
+ }
+ if (cmd->r1 & SD_SPI_R1_NO_RESPONSE) {
+ return ESP_ERR_TIMEOUT;
+ }
+ return ESP_OK;
+}
+
+
+/**
+ * Receiving one or more blocks of data happens as follows:
+ * 1. send command + receive r1 response (SDSPI_CMD_R1_SIZE bytes total)
+ * 2. keep receiving bytes until TOKEN_BLOCK_START is encountered (this may
+ * take a while, depending on card's read speed)
+ * 3. receive up to SDSPI_MAX_DATA_LEN = 512 bytes of actual data
+ * 4. receive 2 bytes of CRC
+ * 5. for multi block transfers, go to step 2
+ *
+ * These steps can be done separately, but that leads to a less than optimal
+ * performance on large transfers because of delays between each step.
+ * For example, if steps 3 and 4 are separate SPI transactions queued one after
+ * another, there will be ~16 microseconds of dead time between end of step 3
+ * and the beginning of step 4. A delay between two blocking SPI transactions
+ * in step 2 is even higher (~60 microseconds).
+ *
+ * To improve read performance the following sequence is adopted:
+ * 1. Do the first transfer: command + r1 response + 8 extra bytes.
+ * Set pre_scan_data_ptr to point to the 8 extra bytes, and set
+ * pre_scan_data_size to 8.
+ * 2. Search pre_scan_data_size bytes for TOKEN_BLOCK_START.
+ * If found, the rest of the bytes contain part of the actual data.
+ * Store pointer to and size of that extra data as extra_data_{ptr,size}.
+ * If not found, fall back to polling for TOKEN_BLOCK_START, 8 bytes at a
+ * time (in poll_data_token function). Deal with extra data in the same way,
+ * by setting extra_data_{ptr,size}.
+ * 3. Receive the remaining 512 - extra_data_size bytes, plus 4 extra bytes
+ * (i.e. 516 - extra_data_size). Of the 4 extra bytes, first two will capture
+ * the CRC value, and the other two will capture 0xff 0xfe sequence
+ * indicating the start of the next block. Actual scanning is done by
+ * setting pre_scan_data_ptr to point to these last 2 bytes, and setting
+ * pre_scan_data_size = 2, then going to step 2 to receive the next block.
+ * When the final block is being received, the number of extra bytes is 2
+ * (only for CRC), because we don't need to wait for start token of the
+ * next block, and some cards are getting confused by these two extra bytes.
+ *
+ * With this approach the delay between blocks of a multi-block transfer is
+ * ~95 microseconds, out of which 35 microseconds are spend doing the CRC check.
+ * Further speedup is possible by pipelining transfers and CRC checks, at an
+ * expense of one extra temporary buffer.
+ */
+static esp_err_t start_command_read_blocks(int slot, sdspi_hw_cmd_t *cmd,
+ uint8_t *data, uint32_t rx_length)
+{
+ bool need_stop_command = rx_length > SDSPI_MAX_DATA_LEN;
+ spi_transaction_t* t_command = get_transaction(slot);
+ *t_command = (spi_transaction_t) {
+ .length = (SDSPI_CMD_R1_SIZE + SDSPI_RESPONSE_MAX_DELAY) * 8,
+ .tx_buffer = cmd,
+ .rx_buffer = cmd,
+ };
+ esp_err_t ret = spi_device_transmit(spi_handle(slot), t_command);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ release_transaction(slot);
+
+ uint8_t* cmd_u8 = (uint8_t*) cmd;
+ size_t pre_scan_data_size = SDSPI_RESPONSE_MAX_DELAY;
+ uint8_t* pre_scan_data_ptr = cmd_u8 + SDSPI_CMD_R1_SIZE;
+
+ /* R1 response is delayed by 1-8 bytes from the request.
+ * This loop searches for the response and writes it to cmd->r1.
+ */
+ while ((cmd->r1 & SD_SPI_R1_NO_RESPONSE) != 0 && pre_scan_data_size > 0) {
+ cmd->r1 = *pre_scan_data_ptr;
+ ++pre_scan_data_ptr;
+ --pre_scan_data_size;
+ }
+ if (cmd->r1 & SD_SPI_R1_NO_RESPONSE) {
+ ESP_LOGD(TAG, "no response token found");
+ return ESP_ERR_TIMEOUT;
+ }
+
+ while (rx_length > 0) {
+ size_t extra_data_size = 0;
+ const uint8_t* extra_data_ptr = NULL;
+ bool need_poll = true;
+
+ for (int i = 0; i < pre_scan_data_size; ++i) {
+ if (pre_scan_data_ptr[i] == TOKEN_BLOCK_START) {
+ extra_data_size = pre_scan_data_size - i - 1;
+ extra_data_ptr = pre_scan_data_ptr + i + 1;
+ need_poll = false;
+ break;
+ }
+ }
+
+ if (need_poll) {
+ // Wait for data to be ready
+ spi_transaction_t* t_poll = get_transaction(slot);
+ ret = poll_data_token(slot, t_poll, cmd_u8 + SDSPI_CMD_R1_SIZE, &extra_data_size, cmd->timeout_ms);
+ release_transaction(slot);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ if (extra_data_size) {
+ extra_data_ptr = cmd_u8 + SDSPI_CMD_R1_SIZE;
+ }
+ }
+
+ // Arrange RX buffer
+ size_t will_receive = MIN(rx_length, SDSPI_MAX_DATA_LEN) - extra_data_size;
+ uint8_t* rx_data;
+ ret = get_block_buf(slot, &rx_data);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+
+ // receive actual data
+ const size_t receive_extra_bytes = (rx_length > SDSPI_MAX_DATA_LEN) ? 4 : 2;
+ memset(rx_data, 0xff, will_receive + receive_extra_bytes);
+ spi_transaction_t* t_data = get_transaction(slot);
+ *t_data = (spi_transaction_t) {
+ .length = (will_receive + receive_extra_bytes) * 8,
+ .rx_buffer = rx_data,
+ .tx_buffer = rx_data
+ };
+
+ ret = spi_device_transmit(spi_handle(slot), t_data);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ release_transaction(slot);
+
+ // CRC bytes need to be received even if CRC is not enabled
+ uint16_t crc = UINT16_MAX;
+ memcpy(&crc, rx_data + will_receive, sizeof(crc));
+
+ // Bytes to scan for the start token
+ pre_scan_data_size = receive_extra_bytes - sizeof(crc);
+ pre_scan_data_ptr = rx_data + will_receive + sizeof(crc);
+
+ // Copy data to the destination buffer
+ memcpy(data + extra_data_size, rx_data, will_receive);
+ if (extra_data_size) {
+ memcpy(data, extra_data_ptr, extra_data_size);
+ }
+
+ // compute CRC of the received data
+ uint16_t crc_of_data = 0;
+ if (data_crc_enabled(slot)) {
+ crc_of_data = sdspi_crc16(data, will_receive + extra_data_size);
+ if (crc_of_data != crc) {
+ ESP_LOGE(TAG, "data CRC failed, got=0x%04x expected=0x%04x", crc_of_data, crc);
+ esp_log_buffer_hex(TAG, data, 16);
+ return ESP_ERR_INVALID_CRC;
+ }
+ }
+
+ data += will_receive + extra_data_size;
+ rx_length -= will_receive + extra_data_size;
+ extra_data_size = 0;
+ extra_data_ptr = NULL;
+ }
+
+ if (need_stop_command) {
+ // To end multi block transfer, send stop command and wait for the
+ // card to process it
+ sdspi_hw_cmd_t stop_cmd;
+ make_hw_cmd(MMC_STOP_TRANSMISSION, 0, cmd->timeout_ms, &stop_cmd);
+ ret = start_command_default(slot, SDSPI_CMD_FLAG_RSP_R1, &stop_cmd);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ if (stop_cmd.r1 != 0) {
+ ESP_LOGD(TAG, "%s: STOP_TRANSMISSION response 0x%02x", __func__, stop_cmd.r1);
+ }
+ spi_transaction_t* t_poll = get_transaction(slot);
+ ret = poll_busy(slot, t_poll, cmd->timeout_ms);
+ release_transaction(slot);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ }
+ return ESP_OK;
+}
+
+static esp_err_t start_command_write_blocks(int slot, sdspi_hw_cmd_t *cmd,
+ const uint8_t *data, uint32_t tx_length)
+{
+ if (card_write_protected(slot)) {
+ ESP_LOGW(TAG, "%s: card write protected", __func__);
+ return ESP_ERR_INVALID_STATE;
+ }
+ spi_transaction_t* t_command = get_transaction(slot);
+ *t_command = (spi_transaction_t) {
+ .length = SDSPI_CMD_R1_SIZE * 8,
+ .tx_buffer = cmd,
+ .rx_buffer = cmd,
+ };
+ esp_err_t ret = spi_device_queue_trans(spi_handle(slot), t_command, 0);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ wait_for_transactions(slot);
+
+ // Poll for command response which may be delayed up to 8 bytes
+ ret = poll_cmd_response(slot, cmd);
+ if (ret != ESP_OK) {
+ ESP_LOGD(TAG, "%s: poll_cmd_response returned 0x%x", __func__, ret);
+ return ret;
+ }
+
+ uint8_t start_token = tx_length <= SDSPI_MAX_DATA_LEN ?
+ TOKEN_BLOCK_START : TOKEN_BLOCK_START_WRITE_MULTI;
+
+ while (tx_length > 0) {
+
+ // Write block start token
+ spi_transaction_t* t_start_token = get_transaction(slot);
+ *t_start_token = (spi_transaction_t) {
+ .length = sizeof(start_token) * 8,
+ .tx_buffer = &start_token
+ };
+ ret = spi_device_queue_trans(spi_handle(slot), t_start_token, 0);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+
+ // Prepare data to be sent
+ size_t will_send = MIN(tx_length, SDSPI_MAX_DATA_LEN);
+ const uint8_t* tx_data = data;
+ if (!ptr_dma_compatible(tx_data)) {
+ // If the pointer can't be used with DMA, copy data into a new buffer
+ uint8_t* tmp;
+ ret = get_block_buf(slot, &tmp);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ memcpy(tmp, tx_data, will_send);
+ tx_data = tmp;
+ }
+
+ // Write data
+ spi_transaction_t* t_data = get_transaction(slot);
+ *t_data = (spi_transaction_t) {
+ .length = will_send * 8,
+ .tx_buffer = tx_data,
+ };
+ ret = spi_device_queue_trans(spi_handle(slot), t_data, 0);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+
+ // Write CRC
+ uint16_t crc = sdspi_crc16(data, will_send);
+ spi_transaction_t* t_crc = get_transaction(slot);
+ *t_crc = (spi_transaction_t) {
+ .length = sizeof(crc) * 8,
+ .tx_buffer = (uint8_t*) &crc,
+ };
+ ret = spi_device_queue_trans(spi_handle(slot), t_crc, 0);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+
+ // Wait for data to be sent
+ wait_for_transactions(slot);
+
+ // Poll for response
+ spi_transaction_t* t_poll = get_transaction(slot);
+ ret = poll_response_token(slot, t_poll, cmd->timeout_ms);
+ release_transaction(slot);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+
+ // Wait for the card to finish writing data
+ t_poll = get_transaction(slot);
+ ret = poll_busy(slot, t_poll, cmd->timeout_ms);
+ release_transaction(slot);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+
+ tx_length -= will_send;
+ data += will_send;
+ }
+
+ if (start_token == TOKEN_BLOCK_START_WRITE_MULTI) {
+ uint8_t stop_token[2] = {
+ TOKEN_BLOCK_STOP_WRITE_MULTI,
+ SDSPI_MOSI_IDLE_VAL
+ };
+ spi_transaction_t* t_stop_token = get_transaction(slot);
+ *t_stop_token = (spi_transaction_t) {
+ .length = sizeof(stop_token) * 8,
+ .tx_buffer = &stop_token,
+ };
+ ret = spi_device_queue_trans(spi_handle(slot), t_stop_token, 0);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ wait_for_transactions(slot);
+
+ spi_transaction_t* t_poll = get_transaction(slot);
+ ret = poll_busy(slot, t_poll, cmd->timeout_ms);
+ release_transaction(slot);
+ if (ret != ESP_OK) {
+ return ret;
+ }
+ }
+
+ return ESP_OK;
+}
diff --git a/components/driver/sdspi_private.h b/components/driver/sdspi_private.h
index 12b0568f14..32500ac777 100644
--- a/components/driver/sdspi_private.h
+++ b/components/driver/sdspi_private.h
@@ -1,99 +1,99 @@
-// Copyright 2015-2017 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.
-
-#pragma once
-
-#include
-#include
-#include "esp_err.h"
-#include "freertos/FreeRTOS.h"
-#include "freertos/queue.h"
-
-
-/// Control tokens used to frame data transfers
-/// (see section 7.3.3 of SD simplified spec)
-
-/// Token sent before single/multi block reads and single block writes
-#define TOKEN_BLOCK_START 0b11111110
-/// Token sent before multi block writes
-#define TOKEN_BLOCK_START_WRITE_MULTI 0b11111100
-/// Token used to stop multi block write (for reads, CMD12 is used instead)
-#define TOKEN_BLOCK_STOP_WRITE_MULTI 0b11111101
-
-/// Data response tokens
-
-/// Mask (high 3 bits are undefined for data response tokens)
-#define TOKEN_RSP_MASK 0b11111
-/// Data accepted
-#define TOKEN_RSP_OK 0b00101
-/// Data rejected due to CRC error
-#define TOKEN_RSP_CRC_ERR 0b01011
-/// Data rejected due to write error
-#define TOKEN_RSP_WRITE_ERR 0b01101
-
-
-/// Data error tokens have format 0b0000xyzw where xyzw are signle bit flags.
-/// MASK and VAL are used to check if a token is an error token
-#define TOKEN_ERR_MASK 0b11110000
-#define TOKEN_ERR_VAL 0b00000000
-
-/// Argument is out of range
-#define TOKEN_ERR_RANGE BIT(3)
-/// Card internal ECC error
-#define TOKEN_ERR_CARD_ECC BIT(2)
-/// Card controller error
-#define TOKEN_ERR_INTERNAL BIT(1)
-/// Card is locked
-#define TOKEN_ERR_LOCKED BIT(0)
-
-
-/// Transfer format in SPI mode. See section 7.3.1.1 of SD simplified spec.
-typedef struct {
- // These fields form the command sent from host to the card (6 bytes)
- uint8_t cmd_index : 6;
- uint8_t transmission_bit : 1;
- uint8_t start_bit : 1;
- uint8_t arguments[4];
- uint8_t stop_bit : 1;
- uint8_t crc7 : 7;
- /// Ncr is the dead time between command and response; should be 0xff
- uint8_t ncr;
- /// Response data, should be set by host to 0xff for read operations
- uint8_t r1;
- /// Up to 16 bytes of response. Luckily, this is aligned on 4 byte boundary.
- uint32_t response[4];
- /// response timeout, in milliseconds
- int timeout_ms;
-} sdspi_hw_cmd_t;
-
-#define SDSPI_CMD_NORESP_SIZE 6 //!< Size of the command without any response
-#define SDSPI_CMD_R1_SIZE 8 //!< Size of the command with R1 response
-#define SDSPI_CMD_R2_SIZE 9 //!< Size of the command with R1b response
-#define SDSPI_CMD_R3_SIZE 12 //!< Size of the command with R3 response
-#define SDSPI_CMD_R7_SIZE 12 //!< Size of the command with R7 response
-
-#define SDSPI_CMD_FLAG_DATA BIT(0) //!< Command has data transfer
-#define SDSPI_CMD_FLAG_WRITE BIT(1) //!< Data is written to the card
-#define SDSPI_CMD_FLAG_RSP_R1 BIT(2) //!< Response format R1 (1 byte)
-#define SDSPI_CMD_FLAG_RSP_R2 BIT(3) //!< Response format R2 (2 bytes)
-#define SDSPI_CMD_FLAG_RSP_R3 BIT(4) //!< Response format R3 (5 bytes)
-#define SDSPI_CMD_FLAG_RSP_R7 BIT(5) //!< Response format R7 (5 bytes)
-#define SDSPI_CMD_FLAG_NORSP BIT(6) //!< Don't expect response (used when sending CMD0 first time).
-
-#define SDSPI_MAX_DATA_LEN 512 //!< Max size of single block transfer
-
-void make_hw_cmd(uint32_t opcode, uint32_t arg, int timeout_ms, sdspi_hw_cmd_t *hw_cmd);
-
-esp_err_t sdspi_host_start_command(int slot, sdspi_hw_cmd_t *cmd,
- void *data, uint32_t data_size, int flags);
+// Copyright 2015-2017 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.
+
+#pragma once
+
+#include
+#include
+#include "esp_err.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/queue.h"
+
+
+/// Control tokens used to frame data transfers
+/// (see section 7.3.3 of SD simplified spec)
+
+/// Token sent before single/multi block reads and single block writes
+#define TOKEN_BLOCK_START 0b11111110
+/// Token sent before multi block writes
+#define TOKEN_BLOCK_START_WRITE_MULTI 0b11111100
+/// Token used to stop multi block write (for reads, CMD12 is used instead)
+#define TOKEN_BLOCK_STOP_WRITE_MULTI 0b11111101
+
+/// Data response tokens
+
+/// Mask (high 3 bits are undefined for data response tokens)
+#define TOKEN_RSP_MASK 0b11111
+/// Data accepted
+#define TOKEN_RSP_OK 0b00101
+/// Data rejected due to CRC error
+#define TOKEN_RSP_CRC_ERR 0b01011
+/// Data rejected due to write error
+#define TOKEN_RSP_WRITE_ERR 0b01101
+
+
+/// Data error tokens have format 0b0000xyzw where xyzw are signle bit flags.
+/// MASK and VAL are used to check if a token is an error token
+#define TOKEN_ERR_MASK 0b11110000
+#define TOKEN_ERR_VAL 0b00000000
+
+/// Argument is out of range
+#define TOKEN_ERR_RANGE BIT(3)
+/// Card internal ECC error
+#define TOKEN_ERR_CARD_ECC BIT(2)
+/// Card controller error
+#define TOKEN_ERR_INTERNAL BIT(1)
+/// Card is locked
+#define TOKEN_ERR_LOCKED BIT(0)
+
+
+/// Transfer format in SPI mode. See section 7.3.1.1 of SD simplified spec.
+typedef struct {
+ // These fields form the command sent from host to the card (6 bytes)
+ uint8_t cmd_index : 6;
+ uint8_t transmission_bit : 1;
+ uint8_t start_bit : 1;
+ uint8_t arguments[4];
+ uint8_t stop_bit : 1;
+ uint8_t crc7 : 7;
+ /// Ncr is the dead time between command and response; should be 0xff
+ uint8_t ncr;
+ /// Response data, should be set by host to 0xff for read operations
+ uint8_t r1;
+ /// Up to 16 bytes of response. Luckily, this is aligned on 4 byte boundary.
+ uint32_t response[4];
+ /// response timeout, in milliseconds
+ int timeout_ms;
+} sdspi_hw_cmd_t;
+
+#define SDSPI_CMD_NORESP_SIZE 6 //!< Size of the command without any response
+#define SDSPI_CMD_R1_SIZE 8 //!< Size of the command with R1 response
+#define SDSPI_CMD_R2_SIZE 9 //!< Size of the command with R1b response
+#define SDSPI_CMD_R3_SIZE 12 //!< Size of the command with R3 response
+#define SDSPI_CMD_R7_SIZE 12 //!< Size of the command with R7 response
+
+#define SDSPI_CMD_FLAG_DATA BIT(0) //!< Command has data transfer
+#define SDSPI_CMD_FLAG_WRITE BIT(1) //!< Data is written to the card
+#define SDSPI_CMD_FLAG_RSP_R1 BIT(2) //!< Response format R1 (1 byte)
+#define SDSPI_CMD_FLAG_RSP_R2 BIT(3) //!< Response format R2 (2 bytes)
+#define SDSPI_CMD_FLAG_RSP_R3 BIT(4) //!< Response format R3 (5 bytes)
+#define SDSPI_CMD_FLAG_RSP_R7 BIT(5) //!< Response format R7 (5 bytes)
+#define SDSPI_CMD_FLAG_NORSP BIT(6) //!< Don't expect response (used when sending CMD0 first time).
+
+#define SDSPI_MAX_DATA_LEN 512 //!< Max size of single block transfer
+
+void make_hw_cmd(uint32_t opcode, uint32_t arg, int timeout_ms, sdspi_hw_cmd_t *hw_cmd);
+
+esp_err_t sdspi_host_start_command(int slot, sdspi_hw_cmd_t *cmd,
+ void *data, uint32_t data_size, int flags);
diff --git a/components/driver/sdspi_transaction.c b/components/driver/sdspi_transaction.c
index 4b9c695846..d25521deaa 100644
--- a/components/driver/sdspi_transaction.c
+++ b/components/driver/sdspi_transaction.c
@@ -17,7 +17,7 @@
#include "esp_log.h"
#include "sys/lock.h"
#include "soc/sdmmc_reg.h"
-#include "soc/sdmmc_struct.h"
+#include "soc/sdmmc_periph.h"
#include "driver/sdmmc_types.h"
#include "driver/sdmmc_defs.h"
#include "driver/sdmmc_host.h"
diff --git a/components/driver/spi_common.c b/components/driver/spi_common.c
index 52f239af3b..aa5495a8cf 100644
--- a/components/driver/spi_common.c
+++ b/components/driver/spi_common.c
@@ -1,4 +1,4 @@
-// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+// Copyright 2015-2018 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.
@@ -15,10 +15,8 @@
#include
#include "driver/spi_master.h"
-#include "soc/gpio_sig_map.h"
-#include "soc/spi_reg.h"
#include "soc/dport_reg.h"
-#include "soc/spi_struct.h"
+#include "soc/spi_periph.h"
#include "rom/ets_sys.h"
#include "esp_types.h"
#include "esp_attr.h"
@@ -32,7 +30,6 @@
#include "driver/gpio.h"
#include "driver/periph_ctrl.h"
#include "esp_heap_caps.h"
-
#include "driver/spi_common.h"
static const char *SPI_TAG = "spi";
@@ -49,109 +46,6 @@ typedef struct spi_device_t spi_device_t;
#define FUNC_SPI 1 //all pins of HSPI and VSPI shares this function number
#define FUNC_GPIO PIN_FUNC_GPIO
-/*
- Stores a bunch of per-spi-peripheral data.
-*/
-typedef struct {
- const uint8_t spiclk_out; //GPIO mux output signals
- const uint8_t spiclk_in;
- const uint8_t spid_out;
- const uint8_t spiq_out;
- const uint8_t spiwp_out;
- const uint8_t spihd_out;
- const uint8_t spid_in; //GPIO mux input signals
- const uint8_t spiq_in;
- const uint8_t spiwp_in;
- const uint8_t spihd_in;
- const uint8_t spics_out[3]; // /CS GPIO output mux signals
- const uint8_t spics_in;
- const uint8_t spiclk_native; //IO pins of IO_MUX muxed signals
- const uint8_t spid_native;
- const uint8_t spiq_native;
- const uint8_t spiwp_native;
- const uint8_t spihd_native;
- const uint8_t spics0_native;
- const uint8_t irq; //irq source for interrupt mux
- const uint8_t irq_dma; //dma irq source for interrupt mux
- const periph_module_t module; //peripheral module, for enabling clock etc
- spi_dev_t *hw; //Pointer to the hardware registers
-} spi_signal_conn_t;
-
-/*
- Bunch of constants for every SPI peripheral: GPIO signals, irqs, hw addr of registers etc
-*/
-static const spi_signal_conn_t io_signal[3] = {
- {
- .spiclk_out = SPICLK_OUT_IDX,
- .spiclk_in = SPICLK_IN_IDX,
- .spid_out = SPID_OUT_IDX,
- .spiq_out = SPIQ_OUT_IDX,
- .spiwp_out = SPIWP_OUT_IDX,
- .spihd_out = SPIHD_OUT_IDX,
- .spid_in = SPID_IN_IDX,
- .spiq_in = SPIQ_IN_IDX,
- .spiwp_in = SPIWP_IN_IDX,
- .spihd_in = SPIHD_IN_IDX,
- .spics_out = {SPICS0_OUT_IDX, SPICS1_OUT_IDX, SPICS2_OUT_IDX},
- .spics_in = SPICS0_IN_IDX,
- .spiclk_native = 6,
- .spid_native = 8,
- .spiq_native = 7,
- .spiwp_native = 10,
- .spihd_native = 9,
- .spics0_native = 11,
- .irq = ETS_SPI1_INTR_SOURCE,
- .irq_dma = ETS_SPI1_DMA_INTR_SOURCE,
- .module = PERIPH_SPI_MODULE,
- .hw = &SPI1
- }, {
- .spiclk_out = HSPICLK_OUT_IDX,
- .spiclk_in = HSPICLK_IN_IDX,
- .spid_out = HSPID_OUT_IDX,
- .spiq_out = HSPIQ_OUT_IDX,
- .spiwp_out = HSPIWP_OUT_IDX,
- .spihd_out = HSPIHD_OUT_IDX,
- .spid_in = HSPID_IN_IDX,
- .spiq_in = HSPIQ_IN_IDX,
- .spiwp_in = HSPIWP_IN_IDX,
- .spihd_in = HSPIHD_IN_IDX,
- .spics_out = {HSPICS0_OUT_IDX, HSPICS1_OUT_IDX, HSPICS2_OUT_IDX},
- .spics_in = HSPICS0_IN_IDX,
- .spiclk_native = 14,
- .spid_native = 13,
- .spiq_native = 12,
- .spiwp_native = 2,
- .spihd_native = 4,
- .spics0_native = 15,
- .irq = ETS_SPI2_INTR_SOURCE,
- .irq_dma = ETS_SPI2_DMA_INTR_SOURCE,
- .module = PERIPH_HSPI_MODULE,
- .hw = &SPI2
- }, {
- .spiclk_out = VSPICLK_OUT_IDX,
- .spiclk_in = VSPICLK_IN_IDX,
- .spid_out = VSPID_OUT_IDX,
- .spiq_out = VSPIQ_OUT_IDX,
- .spiwp_out = VSPIWP_OUT_IDX,
- .spihd_out = VSPIHD_OUT_IDX,
- .spid_in = VSPID_IN_IDX,
- .spiq_in = VSPIQ_IN_IDX,
- .spiwp_in = VSPIWP_IN_IDX,
- .spihd_in = VSPIHD_IN_IDX,
- .spics_out = {VSPICS0_OUT_IDX, VSPICS1_OUT_IDX, VSPICS2_OUT_IDX},
- .spics_in = VSPICS0_IN_IDX,
- .spiclk_native = 18,
- .spid_native = 23,
- .spiq_native = 19,
- .spiwp_native = 22,
- .spihd_native = 21,
- .spics0_native = 5,
- .irq = ETS_SPI3_INTR_SOURCE,
- .irq_dma = ETS_SPI3_DMA_INTR_SOURCE,
- .module = PERIPH_VSPI_MODULE,
- .hw = &SPI3
- }
-};
#define DMA_CHANNEL_ENABLED(dma_chan) (BIT(dma_chan-1))
@@ -165,7 +59,7 @@ static portMUX_TYPE spi_dma_spinlock = portMUX_INITIALIZER_UNLOCKED;
bool spicommon_periph_claim(spi_host_device_t host)
{
bool ret = __sync_bool_compare_and_swap(&spi_periph_claimed[host], false, true);
- if (ret) periph_module_enable(io_signal[host].module);
+ if (ret) periph_module_enable(spi_periph_signal[host].module);
return ret;
}
@@ -173,19 +67,19 @@ bool spicommon_periph_claim(spi_host_device_t host)
bool spicommon_periph_free(spi_host_device_t host)
{
bool ret = __sync_bool_compare_and_swap(&spi_periph_claimed[host], true, false);
- if (ret) periph_module_disable(io_signal[host].module);
+ if (ret) periph_module_disable(spi_periph_signal[host].module);
return ret;
}
int spicommon_irqsource_for_host(spi_host_device_t host)
{
- return io_signal[host].irq;
+ return spi_periph_signal[host].irq;
}
spi_dev_t *spicommon_hw_for_host(spi_host_device_t host)
{
- return io_signal[host].hw;
+ return spi_periph_signal[host].hw;
}
bool spicommon_dma_chan_claim (int dma_chan)
@@ -228,7 +122,7 @@ it should be able to be initialized.
*/
esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_config_t *bus_config, int dma_chan, uint32_t flags, uint32_t* flags_o)
{
- bool native = true;
+ bool use_iomux = true;
uint32_t temp_flag=0;
bool quad_pins_exist = true;
//the MISO should be output capable in slave mode, or in DIO/QIO mode.
@@ -236,24 +130,24 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
//the MOSI should be output capble in master mode, or in DIO/QIO mode.
bool mosi_output = (flags&SPICOMMON_BUSFLAG_MASTER)!=0 || flags&SPICOMMON_BUSFLAG_DUAL;
- //check pins existence and if the selected pins correspond to the native pins of the peripheral
+ //check pins existence and if the selected pins correspond to the iomux pins of the peripheral
if (bus_config->sclk_io_num>=0) {
temp_flag |= SPICOMMON_BUSFLAG_SCLK;
SPI_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(bus_config->sclk_io_num), "sclk not valid", ESP_ERR_INVALID_ARG);
- if (bus_config->sclk_io_num != io_signal[host].spiclk_native) native = false;
+ if (bus_config->sclk_io_num != spi_periph_signal[host].spiclk_iomux_pin) use_iomux = false;
} else {
SPI_CHECK((flags&SPICOMMON_BUSFLAG_SCLK)==0, "sclk pin required.", ESP_ERR_INVALID_ARG);
}
if (bus_config->quadwp_io_num>=0) {
SPI_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(bus_config->quadwp_io_num), "spiwp not valid", ESP_ERR_INVALID_ARG);
- if (bus_config->quadwp_io_num != io_signal[host].spiwp_native) native = false;
+ if (bus_config->quadwp_io_num != spi_periph_signal[host].spiwp_iomux_pin) use_iomux = false;
} else {
quad_pins_exist = false;
SPI_CHECK((flags&SPICOMMON_BUSFLAG_WPHD)==0, "spiwp pin required.", ESP_ERR_INVALID_ARG);
}
if (bus_config->quadhd_io_num>=0) {
SPI_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(bus_config->quadhd_io_num), "spihd not valid", ESP_ERR_INVALID_ARG);
- if (bus_config->quadhd_io_num != io_signal[host].spihd_native) native = false;
+ if (bus_config->quadhd_io_num != spi_periph_signal[host].spihd_iomux_pin) use_iomux = false;
} else {
quad_pins_exist = false;
SPI_CHECK((flags&SPICOMMON_BUSFLAG_WPHD)==0, "spihd pin required.", ESP_ERR_INVALID_ARG);
@@ -265,7 +159,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
} else {
SPI_CHECK(GPIO_IS_VALID_GPIO(bus_config->mosi_io_num), "mosi not valid", ESP_ERR_INVALID_ARG);
}
- if (bus_config->mosi_io_num != io_signal[host].spid_native) native = false;
+ if (bus_config->mosi_io_num != spi_periph_signal[host].spid_iomux_pin) use_iomux = false;
} else {
SPI_CHECK((flags&SPICOMMON_BUSFLAG_MOSI)==0, "mosi pin required.", ESP_ERR_INVALID_ARG);
}
@@ -276,7 +170,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
} else {
SPI_CHECK(GPIO_IS_VALID_GPIO(bus_config->miso_io_num), "miso not valid", ESP_ERR_INVALID_ARG);
}
- if (bus_config->miso_io_num != io_signal[host].spiq_native) native = false;
+ if (bus_config->miso_io_num != spi_periph_signal[host].spiq_iomux_pin) use_iomux = false;
} else {
SPI_CHECK((flags&SPICOMMON_BUSFLAG_MISO)==0, "miso pin required.", ESP_ERR_INVALID_ARG);
}
@@ -287,31 +181,31 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
}
//set flags for QUAD mode according to the existence of wp and hd
if (quad_pins_exist) temp_flag |= SPICOMMON_BUSFLAG_WPHD;
- //check native pins if required.
- SPI_CHECK((flags&SPICOMMON_BUSFLAG_NATIVE_PINS)==0 || native, "not using native pins", ESP_ERR_INVALID_ARG);
+ //check iomux pins if required.
+ SPI_CHECK((flags&SPICOMMON_BUSFLAG_NATIVE_PINS)==0 || use_iomux, "not using iomux pins", ESP_ERR_INVALID_ARG);
- if (native) {
- //All SPI native pin selections resolve to 1, so we put that here instead of trying to figure
+ if (use_iomux) {
+ //All SPI iomux pin selections resolve to 1, so we put that here instead of trying to figure
//out which FUNC_GPIOx_xSPIxx to grab; they all are defined to 1 anyway.
- ESP_LOGD(SPI_TAG, "SPI%d use native pins.", host );
+ ESP_LOGD(SPI_TAG, "SPI%d use iomux pins.", host );
if (bus_config->mosi_io_num >= 0) {
- gpio_iomux_in(bus_config->mosi_io_num, io_signal[host].spid_in);
+ gpio_iomux_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in);
gpio_iomux_out(bus_config->mosi_io_num, FUNC_SPI, false);
}
if (bus_config->miso_io_num >= 0) {
- gpio_iomux_in(bus_config->miso_io_num, io_signal[host].spiq_in);
+ gpio_iomux_in(bus_config->miso_io_num, spi_periph_signal[host].spiq_in);
gpio_iomux_out(bus_config->miso_io_num, FUNC_SPI, false);
}
if (bus_config->quadwp_io_num >= 0) {
- gpio_iomux_in(bus_config->quadwp_io_num, io_signal[host].spiwp_in);
+ gpio_iomux_in(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in);
gpio_iomux_out(bus_config->quadwp_io_num, FUNC_SPI, false);
}
if (bus_config->quadhd_io_num >= 0) {
- gpio_iomux_in(bus_config->quadhd_io_num, io_signal[host].spihd_in);
+ gpio_iomux_in(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in);
gpio_iomux_out(bus_config->quadhd_io_num, FUNC_SPI, false);
}
if (bus_config->sclk_io_num >= 0) {
- gpio_iomux_in(bus_config->sclk_io_num, io_signal[host].spiclk_in);
+ gpio_iomux_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in);
gpio_iomux_out(bus_config->sclk_io_num, FUNC_SPI, false);
}
temp_flag |= SPICOMMON_BUSFLAG_NATIVE_PINS;
@@ -319,42 +213,42 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
//Use GPIO matrix
ESP_LOGD(SPI_TAG, "SPI%d use gpio matrix.", host );
if (bus_config->mosi_io_num >= 0) {
- PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->mosi_io_num], FUNC_GPIO);
if (mosi_output || (temp_flag&SPICOMMON_BUSFLAG_DUAL)) {
gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT_OUTPUT);
- gpio_matrix_out(bus_config->mosi_io_num, io_signal[host].spid_out, false, false);
+ gpio_matrix_out(bus_config->mosi_io_num, spi_periph_signal[host].spid_out, false, false);
} else {
gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT);
}
- gpio_matrix_in(bus_config->mosi_io_num, io_signal[host].spid_in, false);
+ gpio_matrix_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in, false);
+ PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->mosi_io_num], FUNC_GPIO);
}
if (bus_config->miso_io_num >= 0) {
- PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->miso_io_num], FUNC_GPIO);
if (miso_output || (temp_flag&SPICOMMON_BUSFLAG_DUAL)) {
gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT_OUTPUT);
- gpio_matrix_out(bus_config->miso_io_num, io_signal[host].spiq_out, false, false);
+ gpio_matrix_out(bus_config->miso_io_num, spi_periph_signal[host].spiq_out, false, false);
} else {
gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT);
}
- gpio_matrix_in(bus_config->miso_io_num, io_signal[host].spiq_in, false);
+ gpio_matrix_in(bus_config->miso_io_num, spi_periph_signal[host].spiq_in, false);
+ PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->miso_io_num], FUNC_GPIO);
}
if (bus_config->quadwp_io_num >= 0) {
- PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num], FUNC_GPIO);
gpio_set_direction(bus_config->quadwp_io_num, GPIO_MODE_INPUT_OUTPUT);
- gpio_matrix_out(bus_config->quadwp_io_num, io_signal[host].spiwp_out, false, false);
- gpio_matrix_in(bus_config->quadwp_io_num, io_signal[host].spiwp_in, false);
+ gpio_matrix_out(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_out, false, false);
+ gpio_matrix_in(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in, false);
+ PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num], FUNC_GPIO);
}
if (bus_config->quadhd_io_num >= 0) {
- PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num], FUNC_GPIO);
gpio_set_direction(bus_config->quadhd_io_num, GPIO_MODE_INPUT_OUTPUT);
- gpio_matrix_out(bus_config->quadhd_io_num, io_signal[host].spihd_out, false, false);
- gpio_matrix_in(bus_config->quadhd_io_num, io_signal[host].spihd_in, false);
+ gpio_matrix_out(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_out, false, false);
+ gpio_matrix_in(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in, false);
+ PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num], FUNC_GPIO);
}
if (bus_config->sclk_io_num >= 0) {
- PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->sclk_io_num], FUNC_GPIO);
gpio_set_direction(bus_config->sclk_io_num, GPIO_MODE_INPUT_OUTPUT);
- gpio_matrix_out(bus_config->sclk_io_num, io_signal[host].spiclk_out, false, false);
- gpio_matrix_in(bus_config->sclk_io_num, io_signal[host].spiclk_in, false);
+ gpio_matrix_out(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_out, false, false);
+ gpio_matrix_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in, false);
+ PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->sclk_io_num], FUNC_GPIO);
}
}
@@ -378,39 +272,61 @@ static void reset_func_to_gpio(int func)
esp_err_t spicommon_bus_free_io(spi_host_device_t host)
{
- if (REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spid_native], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spid_native], PIN_FUNC_GPIO);
- if (REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spiq_native], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spiq_native], PIN_FUNC_GPIO);
- if (REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spiclk_native], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spiclk_native], PIN_FUNC_GPIO);
- if (REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spiwp_native], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spiwp_native], PIN_FUNC_GPIO);
- if (REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spihd_native], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spihd_native], PIN_FUNC_GPIO);
- reset_func_to_gpio(io_signal[host].spid_out);
- reset_func_to_gpio(io_signal[host].spiq_out);
- reset_func_to_gpio(io_signal[host].spiclk_out);
- reset_func_to_gpio(io_signal[host].spiwp_out);
- reset_func_to_gpio(io_signal[host].spihd_out);
+ if (REG_GET_FIELD(GPIO_PIN_MUX_REG[spi_periph_signal[host].spid_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[spi_periph_signal[host].spid_iomux_pin], PIN_FUNC_GPIO);
+ if (REG_GET_FIELD(GPIO_PIN_MUX_REG[spi_periph_signal[host].spiq_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[spi_periph_signal[host].spiq_iomux_pin], PIN_FUNC_GPIO);
+ if (REG_GET_FIELD(GPIO_PIN_MUX_REG[spi_periph_signal[host].spiclk_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[spi_periph_signal[host].spiclk_iomux_pin], PIN_FUNC_GPIO);
+ if (REG_GET_FIELD(GPIO_PIN_MUX_REG[spi_periph_signal[host].spiwp_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[spi_periph_signal[host].spiwp_iomux_pin], PIN_FUNC_GPIO);
+ if (REG_GET_FIELD(GPIO_PIN_MUX_REG[spi_periph_signal[host].spihd_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[spi_periph_signal[host].spihd_iomux_pin], PIN_FUNC_GPIO);
+ reset_func_to_gpio(spi_periph_signal[host].spid_out);
+ reset_func_to_gpio(spi_periph_signal[host].spiq_out);
+ reset_func_to_gpio(spi_periph_signal[host].spiclk_out);
+ reset_func_to_gpio(spi_periph_signal[host].spiwp_out);
+ reset_func_to_gpio(spi_periph_signal[host].spihd_out);
+ return ESP_OK;
+}
+
+esp_err_t spicommon_bus_free_io_cfg(const spi_bus_config_t *bus_cfg)
+{
+ int pin_array[] = {
+ bus_cfg->mosi_io_num,
+ bus_cfg->miso_io_num,
+ bus_cfg->sclk_io_num,
+ bus_cfg->quadwp_io_num,
+ bus_cfg->quadhd_io_num,
+ };
+ for (int i = 0; i < sizeof(pin_array)/sizeof(int); i ++) {
+ const int io = pin_array[i];
+ if (io >= 0 && GPIO_IS_VALID_GPIO(io)) gpio_reset_pin(io);
+ }
return ESP_OK;
}
void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, int force_gpio_matrix)
{
- if (!force_gpio_matrix && cs_io_num == io_signal[host].spics0_native && cs_num == 0) {
+ if (!force_gpio_matrix && cs_io_num == spi_periph_signal[host].spics0_iomux_pin && cs_num == 0) {
//The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define.
- gpio_iomux_in(cs_io_num, io_signal[host].spics_in);
+ gpio_iomux_in(cs_io_num, spi_periph_signal[host].spics_in);
gpio_iomux_out(cs_io_num, FUNC_SPI, false);
} else {
//Use GPIO matrix
+ gpio_matrix_out(cs_io_num, spi_periph_signal[host].spics_out[cs_num], false, false);
+ if (cs_num == 0) gpio_matrix_in(cs_io_num, spi_periph_signal[host].spics_in, false);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cs_io_num], FUNC_GPIO);
- gpio_matrix_out(cs_io_num, io_signal[host].spics_out[cs_num], false, false);
- if (cs_num == 0) gpio_matrix_in(cs_io_num, io_signal[host].spics_in, false);
}
}
void spicommon_cs_free(spi_host_device_t host, int cs_io_num)
{
- if (cs_io_num == 0 && REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spics0_native], MCU_SEL) == 1) {
- PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spics0_native], PIN_FUNC_GPIO);
+ if (cs_io_num == 0 && REG_GET_FIELD(GPIO_PIN_MUX_REG[spi_periph_signal[host].spics0_iomux_pin], MCU_SEL) == 1) {
+ PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[spi_periph_signal[host].spics0_iomux_pin], PIN_FUNC_GPIO);
}
- reset_func_to_gpio(io_signal[host].spics_out[cs_io_num]);
+ reset_func_to_gpio(spi_periph_signal[host].spics_out[cs_io_num]);
+}
+
+void spicommon_cs_free_io(int cs_gpio_num)
+{
+ assert(cs_gpio_num>=0 && GPIO_IS_VALID_GPIO(cs_gpio_num));
+ gpio_reset_pin(cs_gpio_num);
}
//Set up a list of dma descriptors. dmadesc is an array of descriptors. Data is the buffer to point to.
diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c
index 4e6a51a5e5..5728bd45e9 100644
--- a/components/driver/spi_master.c
+++ b/components/driver/spi_master.c
@@ -1,4 +1,4 @@
-// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+// Copyright 2015-2018 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.
@@ -21,13 +21,13 @@ is a combination of SPI port and CS pin, plus some information about the specifi
The essence of the interface to a device is a set of queues; one per device. The idea is that to send something to a SPI
device, you allocate a transaction descriptor. It contains some information about the transfer like the lenghth, address,
-command etc, plus pointers to transmit and receive buffer. The address of this block gets pushed into the transmit queue.
-The SPI driver does its magic, and sends and retrieves the data eventually. The data gets written to the receive buffers,
+command etc, plus pointers to transmit and receive buffer. The address of this block gets pushed into the transmit queue.
+The SPI driver does its magic, and sends and retrieves the data eventually. The data gets written to the receive buffers,
if needed the transaction descriptor is modified to indicate returned parameters and the entire thing goes into the return
queue, where whatever software initiated the transaction can retrieve it.
-The entire thing is run from the SPI interrupt handler. If SPI is done transmitting/receiving but nothing is in the queue,
-it will not clear the SPI interrupt but just disable it. This way, when a new thing is sent, pushing the packet into the send
+The entire thing is run from the SPI interrupt handler. If SPI is done transmitting/receiving but nothing is in the queue,
+it will not clear the SPI interrupt but just disable it. This way, when a new thing is sent, pushing the packet into the send
queue and re-enabling the interrupt will trigger the interrupt again, which can then take care of the sending.
*/
@@ -36,10 +36,8 @@ queue and re-enabling the interrupt will trigger the interrupt again, which can
#include
#include "driver/spi_common.h"
#include "driver/spi_master.h"
-#include "soc/gpio_sig_map.h"
-#include "soc/spi_reg.h"
#include "soc/dport_reg.h"
-#include "soc/spi_struct.h"
+#include "soc/spi_periph.h"
#include "rom/ets_sys.h"
#include "esp_types.h"
#include "esp_attr.h"
@@ -66,10 +64,22 @@ typedef typeof(SPI1.clock) spi_clock_reg_t;
#define NO_CS 3 //Number of CS pins per SPI host
+#ifdef CONFIG_SPI_MASTER_ISR_IN_IRAM
+#define SPI_MASTER_ISR_ATTR IRAM_ATTR
+#else
+#define SPI_MASTER_ISR_ATTR
+#endif
+
+#ifdef CONFIG_SPI_MASTER_IN_IRAM
+#define SPI_MASTER_ATTR IRAM_ATTR
+#else
+#define SPI_MASTER_ATTR
+#endif
+
/// struct to hold private transaction data (like tx and rx buffer for DMA).
-typedef struct {
- spi_transaction_t *trans;
+typedef struct {
+ spi_transaction_t *trans;
uint32_t *buffer_to_send; //equals to tx_data, if SPI_TRANS_USE_RXDATA is applied; otherwise if original buffer wasn't in DMA-capable memory, this gets the address of a temporary buffer that is;
//otherwise sets to the original buffer or NULL if no buffer is assigned.
uint32_t *buffer_to_rcv; // similar to buffer_to_send
@@ -87,6 +97,7 @@ typedef struct {
uint32_t flags;
int dma_chan;
int max_transfer_sz;
+ spi_bus_config_t bus_cfg;
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_handle_t pm_lock;
#endif
@@ -96,6 +107,7 @@ typedef struct {
spi_clock_reg_t reg;
int eff_clk;
int dummy_num;
+ int miso_delay;
} clock_config_t;
struct spi_device_t {
@@ -110,9 +122,9 @@ static spi_host_t *spihost[3];
static const char *SPI_TAG = "spi_master";
-#define SPI_CHECK(a, str, ret_val) \
+#define SPI_CHECK(a, str, ret_val, ...) \
if (!(a)) { \
- ESP_LOGE(SPI_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
+ ESP_LOGE(SPI_TAG,"%s(%d): "str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
return (ret_val); \
}
@@ -147,6 +159,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
goto cleanup;
}
memset(spihost[host], 0, sizeof(spi_host_t));
+ memcpy( &spihost[host]->bus_cfg, bus_config, sizeof(spi_bus_config_t));
#ifdef CONFIG_PM_ENABLE
err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi_master",
&spihost[host]->pm_lock);
@@ -177,8 +190,12 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
goto cleanup;
}
}
-
- err = esp_intr_alloc(spicommon_irqsource_for_host(host), ESP_INTR_FLAG_INTRDISABLED, spi_intr, (void*)spihost[host], &spihost[host]->intr);
+
+ int flags = ESP_INTR_FLAG_INTRDISABLED;
+#ifdef CONFIG_SPI_MASTER_ISR_IN_IRAM
+ flags |= ESP_INTR_FLAG_IRAM;
+#endif
+ err = esp_intr_alloc(spicommon_irqsource_for_host(host), flags, spi_intr, (void*)spihost[host], &spihost[host]->intr);
if (err != ESP_OK) {
ret = err;
goto cleanup;
@@ -207,7 +224,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
spihost[host]->hw->slave.wr_sta_inten=0;
//Force a transaction done interrupt. This interrupt won't fire yet because we initialized the SPI interrupt as
- //disabled. This way, we can just enable the SPI interrupt and the interrupt handler will kick in, handling
+ //disabled. This way, we can just enable the SPI interrupt and the interrupt handler will kick in, handling
//any transactions that are queued.
spihost[host]->hw->slave.trans_inten=1;
spihost[host]->hw->slave.trans_done=1;
@@ -238,6 +255,7 @@ esp_err_t spi_bus_free(spi_host_device_t host)
for (x=0; xdevice[x]==NULL, "not all CSses freed", ESP_ERR_INVALID_STATE);
}
+ spicommon_bus_free_io_cfg(&spihost[host]->bus_cfg);
if ( spihost[host]->dma_chan > 0 ) {
spicommon_dma_chan_free ( spihost[host]->dma_chan );
@@ -256,14 +274,38 @@ esp_err_t spi_bus_free(spi_host_device_t host)
return ESP_OK;
}
-static inline uint32_t spi_dummy_limit(bool gpio_is_used)
+void spi_get_timing(bool gpio_is_used, int input_delay_ns, int eff_clk, int* dummy_o, int* cycles_remain_o)
{
- const int apbclk=APB_CLK_FREQ;
- if (!gpio_is_used) {
- return apbclk; //dummy bit workaround is not used when native pins are used
+ const int apbclk_kHz = APB_CLK_FREQ/1000;
+ const int apbclk_n = APB_CLK_FREQ/eff_clk;
+ const int gpio_delay_ns=(gpio_is_used?25:0);
+
+ //calculate how many apb clocks a period has, the 1 is to compensate in case ``input_delay_ns`` is rounded off.
+ int apb_period_n = (1 + input_delay_ns + gpio_delay_ns)*apbclk_kHz/1000/1000;
+ int dummy_required = apb_period_n/apbclk_n;
+
+ int miso_delay = 0;
+ if (dummy_required > 0) {
+ //due to the clock delay between master and slave, there's a range in which data is random
+ //give MISO a delay if needed to make sure we sample at the time MISO is stable
+ miso_delay = (dummy_required+1)*apbclk_n-apb_period_n-1;
} else {
- return apbclk/2; //the dummy bit workaround is used when freq is 40MHz and GPIO matrix is used.
+ //if the dummy is not required, maybe we should also delay half a SPI clock if the data comes too early
+ if (apb_period_n*4 <= apbclk_n) miso_delay = -1;
}
+ if (dummy_o!=NULL) *dummy_o = dummy_required;
+ if (cycles_remain_o!=NULL) *cycles_remain_o = miso_delay;
+ ESP_LOGD(SPI_TAG,"eff: %d, limit: %dk(/%d), %d dummy, %d delay", eff_clk/1000, apbclk_kHz/(apb_period_n+1), apb_period_n, dummy_required, miso_delay);
+}
+
+int spi_get_freq_limit(bool gpio_is_used, int input_delay_ns)
+{
+ const int apbclk_kHz = APB_CLK_FREQ/1000;
+ const int gpio_delay_ns=(gpio_is_used?25:0);
+
+ //calculate how many apb clocks a period has, the 1 is to compensate in case ``input_delay_ns`` is rounded off.
+ int apb_period_n = (1 + input_delay_ns + gpio_delay_ns)*apbclk_kHz/1000/1000;
+ return APB_CLK_FREQ/(apb_period_n+1);
}
/*
@@ -276,6 +318,9 @@ esp_err_t spi_bus_add_device(spi_host_device_t host, const spi_device_interface_
int apbclk=APB_CLK_FREQ;
int eff_clk;
int duty_cycle;
+ int dummy_required;
+ int miso_delay;
+
spi_clock_reg_t clk_reg;
SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
SPI_CHECK(spihost[host]!=NULL, "host not initialized", ESP_ERR_INVALID_STATE);
@@ -288,18 +333,22 @@ esp_err_t spi_bus_add_device(spi_host_device_t host, const spi_device_interface_
SPI_CHECK(freecs!=NO_CS, "no free cs pins for host", ESP_ERR_NOT_FOUND);
//The hardware looks like it would support this, but actually setting cs_ena_pretrans when transferring in full
//duplex mode does absolutely nothing on the ESP32.
- SPI_CHECK(dev_config->cs_ena_pretrans==0 || (dev_config->flags & SPI_DEVICE_HALFDUPLEX), "cs pretrans delay incompatible with full-duplex", ESP_ERR_INVALID_ARG);
-
- //Speeds >=40MHz over GPIO matrix needs a dummy cycle, but these don't work for full-duplex connections.
+ SPI_CHECK( dev_config->cs_ena_pretrans <= 1 || (dev_config->address_bits == 0 && dev_config->command_bits == 0) ||
+ (dev_config->flags & SPI_DEVICE_HALFDUPLEX), "In full-duplex mode, only support cs pretrans delay = 1 and without address_bits and command_bits", ESP_ERR_INVALID_ARG);
+
duty_cycle = (dev_config->duty_cycle_pos==0? 128: dev_config->duty_cycle_pos);
- eff_clk = spi_cal_clock(apbclk, dev_config->clock_speed_hz, duty_cycle, (uint32_t*)&clk_reg);
- uint32_t dummy_limit = spi_dummy_limit(!(spihost[host]->flags&SPICOMMON_BUSFLAG_NATIVE_PINS));
- SPI_CHECK( dev_config->flags & SPI_DEVICE_HALFDUPLEX || (eff_clk/1000/1000) < (dummy_limit/1000/1000) ||
+ eff_clk = spi_cal_clock(apbclk, dev_config->clock_speed_hz, duty_cycle, (uint32_t*)&clk_reg);
+ int freq_limit = spi_get_freq_limit(!(spihost[host]->flags&SPICOMMON_BUSFLAG_NATIVE_PINS), dev_config->input_delay_ns);
+ //GPIO matrix can only change data at 80Mhz rate, which only allows 40MHz SPI clock.
+ SPI_CHECK(eff_clk <= 40*1000*1000 || spihost[host]->flags&SPICOMMON_BUSFLAG_NATIVE_PINS, "80MHz only supported on iomux pins", ESP_ERR_INVALID_ARG);
+ //Speed >=40MHz over GPIO matrix needs a dummy cycle, but these don't work for full-duplex connections.
+ spi_get_timing(!(spihost[host]->flags&SPICOMMON_BUSFLAG_NATIVE_PINS), dev_config->input_delay_ns, eff_clk, &dummy_required, &miso_delay);
+ SPI_CHECK( dev_config->flags & SPI_DEVICE_HALFDUPLEX || dummy_required == 0 ||
dev_config->flags & SPI_DEVICE_NO_DUMMY,
-"When GPIO matrix is used in full-duplex mode at frequency > 26MHz, device cannot read correct data.\n\
+"When GPIO matrix is used in full-duplex mode at frequency > %.1fMHz, device cannot read correct data.\n\
Please note the SPI can only work at divisors of 80MHz, and the driver always tries to find the closest frequency to your configuration.\n\
-Specify ``SPI_DEVICE_NO_DUMMY`` to ignore this checking. Then you can output data at higher speed, or read data at your own risk.",
- ESP_ERR_INVALID_ARG );
+Specify ``SPI_DEVICE_NO_DUMMY`` to ignore this checking. Then you can output data at higher speed, or read data at your own risk.",
+ ESP_ERR_INVALID_ARG, freq_limit/1000./1000 );
//Allocate memory for device
spi_device_t *dev=malloc(sizeof(spi_device_t));
@@ -310,17 +359,18 @@ Specify ``SPI_DEVICE_NO_DUMMY`` to ignore this checking. Then you can output dat
//Allocate queues, set defaults
dev->trans_queue=xQueueCreate(dev_config->queue_size, sizeof(spi_trans_priv));
dev->ret_queue=xQueueCreate(dev_config->queue_size, sizeof(spi_trans_priv));
- if (!dev->trans_queue || !dev->ret_queue) goto nomem;
+ if (!dev->trans_queue || !dev->ret_queue) goto nomem;
dev->host=spihost[host];
//We want to save a copy of the dev config in the dev struct.
memcpy(&dev->cfg, dev_config, sizeof(spi_device_interface_config_t));
dev->cfg.duty_cycle_pos = duty_cycle;
- // TODO: if we have to change the apb clock among transactions, re-calculate this each time the apb clock lock is acquired.
+ // TODO: if we have to change the apb clock among transactions, re-calculate this each time the apb clock lock is acquired.
dev->clk_cfg= (clock_config_t) {
.eff_clk = eff_clk,
- .dummy_num = (dev->clk_cfg.eff_clk >= dummy_limit? 1: 0),
+ .dummy_num = dummy_required,
.reg = clk_reg,
+ .miso_delay = miso_delay,
};
//Set CS pin, CS options
@@ -338,6 +388,8 @@ Specify ``SPI_DEVICE_NO_DUMMY`` to ignore this checking. Then you can output dat
} else {
spihost[host]->hw->pin.master_cs_pol &= (1<hw->ctrl2.mosi_delay_mode = 0;
+ spihost[host]->hw->ctrl2.mosi_delay_num = 0;
*handle=dev;
ESP_LOGD(SPI_TAG, "SPI%d: New device added to CS%d, effective clock: %dkHz", host, freecs, dev->clk_cfg.eff_clk/1000);
return ESP_OK;
@@ -361,6 +413,10 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle)
SPI_CHECK(handle->host->cur_cs == NO_CS || handle->host->device[handle->host->cur_cs]!=handle, "Have unfinished transactions", ESP_ERR_INVALID_STATE);
SPI_CHECK(uxQueueMessagesWaiting(handle->ret_queue)==0, "Have unfinished transactions", ESP_ERR_INVALID_STATE);
+ //return
+ int spics_io_num = handle->cfg.spics_io_num;
+ if (spics_io_num >= 0) spicommon_cs_free_io(spics_io_num);
+
//Kill queues
vQueueDelete(handle->trans_queue);
vQueueDelete(handle->ret_queue);
@@ -445,7 +501,7 @@ static inline void spi_set_clock(spi_dev_t *hw, spi_clock_reg_t reg) {
//This is run in interrupt context and apart from initialization and destruction, this is the only code
//touching the host (=spihost[x]) variable. The rest of the data arrives in queues. That is why there are
//no muxes in this code.
-static void IRAM_ATTR spi_intr(void *arg)
+static void SPI_MASTER_ISR_ATTR spi_intr(void *arg)
{
int i;
BaseType_t r;
@@ -460,7 +516,7 @@ static void IRAM_ATTR spi_intr(void *arg)
/*------------ deal with the in-flight transaction -----------------*/
if (host->cur_cs != NO_CS) {
spi_transaction_t *cur_trans = host->cur_trans_buf.trans;
- //Okay, transaction is done.
+ //Okay, transaction is done.
if (host->cur_trans_buf.buffer_to_rcv && host->dma_chan == 0 ) {
//Need to copy from SPI regs to result buffer.
for (int x=0; x < cur_trans->rxlength; x+=32) {
@@ -474,7 +530,7 @@ static void IRAM_ATTR spi_intr(void *arg)
//Call post-transaction callback, if any
if (host->device[host->cur_cs]->cfg.post_cb) host->device[host->cur_cs]->cfg.post_cb(cur_trans);
//Return transaction descriptor.
- xQueueSendFromISR(host->device[host->cur_cs]->ret_queue, &host->cur_trans_buf, &do_yield);
+ xQueueSendFromISR(host->device[host->cur_cs]->ret_queue, &host->cur_trans_buf, &do_yield);
host->cur_cs = NO_CS;
}
//Tell common code DMA workaround that our DMA channel is idle. If needed, the code will do a DMA reset.
@@ -505,46 +561,27 @@ static void IRAM_ATTR spi_intr(void *arg)
host->cur_cs=i;
//We should be done with the transmission.
assert(host->hw->cmd.usr == 0);
-
+
//Reconfigure according to device settings, but only if we change CSses.
if (i!=host->prev_cs) {
- const int apbclk=APB_CLK_FREQ;
- int effclk=dev->clk_cfg.eff_clk;
spi_set_clock(host->hw, dev->clk_cfg.reg);
//Configure bit order
host->hw->ctrl.rd_bit_order=(dev->cfg.flags & SPI_DEVICE_RXBIT_LSBFIRST)?1:0;
host->hw->ctrl.wr_bit_order=(dev->cfg.flags & SPI_DEVICE_TXBIT_LSBFIRST)?1:0;
-
- //Configure polarity
- //SPI iface needs to be configured for a delay in some cases.
- int nodelay=0;
- if ((host->flags&SPICOMMON_BUSFLAG_NATIVE_PINS)!=0) {
- if (effclk >= apbclk/2) {
- nodelay=1;
- }
- } else {
- uint32_t delay_limit = apbclk/4;
- if (effclk >= delay_limit) {
- nodelay=1;
- }
- }
+ //Configure polarity
if (dev->cfg.mode==0) {
host->hw->pin.ck_idle_edge=0;
host->hw->user.ck_out_edge=0;
- host->hw->ctrl2.miso_delay_mode=nodelay?0:2;
} else if (dev->cfg.mode==1) {
host->hw->pin.ck_idle_edge=0;
host->hw->user.ck_out_edge=1;
- host->hw->ctrl2.miso_delay_mode=nodelay?0:1;
} else if (dev->cfg.mode==2) {
host->hw->pin.ck_idle_edge=1;
host->hw->user.ck_out_edge=1;
- host->hw->ctrl2.miso_delay_mode=nodelay?0:1;
} else if (dev->cfg.mode==3) {
host->hw->pin.ck_idle_edge=1;
host->hw->user.ck_out_edge=0;
- host->hw->ctrl2.miso_delay_mode=nodelay?0:2;
}
//Configure misc stuff
host->hw->user.doutdin=(dev->cfg.flags & SPI_DEVICE_HALFDUPLEX)?0:1;
@@ -552,8 +589,11 @@ static void IRAM_ATTR spi_intr(void *arg)
host->hw->ctrl2.setup_time=dev->cfg.cs_ena_pretrans-1;
host->hw->user.cs_setup=dev->cfg.cs_ena_pretrans?1:0;
- host->hw->ctrl2.hold_time=dev->cfg.cs_ena_posttrans-1;
- host->hw->user.cs_hold=(dev->cfg.cs_ena_posttrans)?1:0;
+ //set hold_time to 0 will not actually append delay to CS
+ //set it to 1 since we do need at least one clock of hold time in most cases
+ host->hw->ctrl2.hold_time=dev->cfg.cs_ena_posttrans;
+ if ( host->hw->ctrl2.hold_time == 0 ) host->hw->ctrl2.hold_time = 1;
+ host->hw->user.cs_hold=1;
//Configure CS pin
host->hw->pin.cs0_dis=(i==0)?0:1;
@@ -607,13 +647,14 @@ static void IRAM_ATTR spi_intr(void *arg)
extra_dummy=dev->clk_cfg.dummy_num;
}
} else {
- //DMA temporary workaround: let RX DMA work somehow to avoid the issue in ESP32 v0/v1 silicon
+ //DMA temporary workaround: let RX DMA work somehow to avoid the issue in ESP32 v0/v1 silicon
if (host->dma_chan != 0 ) {
host->hw->dma_in_link.addr=0;
host->hw->dma_in_link.start=1;
}
}
+
if (trans_buf->buffer_to_send) {
if (host->dma_chan == 0) {
//Need to copy data to registers manually
@@ -634,10 +675,31 @@ static void IRAM_ATTR spi_intr(void *arg)
}
}
+ //SPI iface needs to be configured for a delay in some cases.
//configure dummy bits
host->hw->user.usr_dummy=(dev->cfg.dummy_bits+extra_dummy)?1:0;
host->hw->user1.usr_dummy_cyclelen=dev->cfg.dummy_bits+extra_dummy-1;
+ int miso_long_delay = 0;
+ if (dev->clk_cfg.miso_delay<0) {
+ //if the data comes too late, delay half a SPI clock to improve reading
+ miso_long_delay = 1;
+ host->hw->ctrl2.miso_delay_num = 0;
+ } else {
+ //if the data is so fast that dummy_bit is used, delay some apb clocks to meet the timing
+ host->hw->ctrl2.miso_delay_num = (extra_dummy? dev->clk_cfg.miso_delay: 0);
+ }
+
+ if (dev->cfg.mode==0) {
+ host->hw->ctrl2.miso_delay_mode=miso_long_delay?2:0;
+ } else if (dev->cfg.mode==1) {
+ host->hw->ctrl2.miso_delay_mode=miso_long_delay?1:0;
+ } else if (dev->cfg.mode==2) {
+ host->hw->ctrl2.miso_delay_mode=miso_long_delay?1:0;
+ } else if (dev->cfg.mode==3) {
+ host->hw->ctrl2.miso_delay_mode=miso_long_delay?2:0;
+ }
+
host->hw->mosi_dlen.usr_mosi_dbitlen=trans->length-1;
if ( dev->cfg.flags & SPI_DEVICE_HALFDUPLEX ) {
host->hw->miso_dlen.usr_miso_dbitlen=trans->rxlength-1;
@@ -648,27 +710,39 @@ static void IRAM_ATTR spi_intr(void *arg)
//Configure bit sizes, load addr and command
int cmdlen;
- if ( trans->flags & SPI_TRANS_VARIABLE_CMD ) {
- cmdlen = ((spi_transaction_ext_t*)trans)->command_bits;
- } else {
- cmdlen = dev->cfg.command_bits;
- }
int addrlen;
- if ( trans->flags & SPI_TRANS_VARIABLE_ADDR ) {
- addrlen = ((spi_transaction_ext_t*)trans)->address_bits;
+ if (!(dev->cfg.flags & SPI_DEVICE_HALFDUPLEX) && dev->cfg.cs_ena_pretrans != 0) {
+ /* The command and address phase is not compatible with cs_ena_pretrans
+ * in full duplex mode.
+ */
+ cmdlen = 0;
+ addrlen = 0;
} else {
- addrlen = dev->cfg.address_bits;
+ if (trans->flags & SPI_TRANS_VARIABLE_CMD) {
+ cmdlen = ((spi_transaction_ext_t *)trans)->command_bits;
+ } else {
+ cmdlen = dev->cfg.command_bits;
+ }
+ if (trans->flags & SPI_TRANS_VARIABLE_ADDR) {
+ addrlen = ((spi_transaction_ext_t *)trans)->address_bits;
+ } else {
+ addrlen = dev->cfg.address_bits;
+ }
}
+
host->hw->user1.usr_addr_bitlen=addrlen-1;
host->hw->user2.usr_command_bitlen=cmdlen-1;
host->hw->user.usr_addr=addrlen?1:0;
host->hw->user.usr_command=cmdlen?1:0;
- // output command will be sent from bit 7 to 0 of command_value, and then bit 15 to 8 of the same register field.
- uint16_t command = trans->cmd << (16-cmdlen); //shift to MSB
- host->hw->user2.usr_command_value = (command>>8)|(command<<8); //swap the first and second byte
- // shift the address to MSB of addr (and maybe slv_wr_status) register.
- // output address will be sent from MSB to LSB of addr register, then comes the MSB to LSB of slv_wr_status register.
+ /* Output command will be sent from bit 7 to 0 of command_value, and
+ * then bit 15 to 8 of the same register field. Shift and swap to send
+ * more straightly.
+ */
+ host->hw->user2.usr_command_value = SPI_SWAP_DATA_TX(trans->cmd, cmdlen);
+
+ // shift the address to MSB of addr (and maybe slv_wr_status) register.
+ // output address will be sent from MSB to LSB of addr register, then comes the MSB to LSB of slv_wr_status register.
if (addrlen>32) {
host->hw->addr = trans->addr >> (addrlen- 32);
host->hw->slv_wr_status = trans->addr << (64 - addrlen);
@@ -688,18 +762,18 @@ static void IRAM_ATTR spi_intr(void *arg)
}
-esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *trans_desc, TickType_t ticks_to_wait)
+esp_err_t SPI_MASTER_ATTR spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *trans_desc, TickType_t ticks_to_wait)
{
esp_err_t ret = ESP_OK;
BaseType_t r;
SPI_CHECK(handle!=NULL, "invalid dev handle", ESP_ERR_INVALID_ARG);
- //check transmission length
+ //check transmission length
SPI_CHECK((trans_desc->flags & SPI_TRANS_USE_RXDATA)==0 ||trans_desc->rxlength <= 32, "rxdata transfer > 32 bits without configured DMA", ESP_ERR_INVALID_ARG);
SPI_CHECK((trans_desc->flags & SPI_TRANS_USE_TXDATA)==0 ||trans_desc->length <= 32, "txdata transfer > 32 bits without configured DMA", ESP_ERR_INVALID_ARG);
SPI_CHECK(trans_desc->length <= handle->host->max_transfer_sz*8, "txdata transfer > host maximum", ESP_ERR_INVALID_ARG);
SPI_CHECK(trans_desc->rxlength <= handle->host->max_transfer_sz*8, "rxdata transfer > host maximum", ESP_ERR_INVALID_ARG);
SPI_CHECK((handle->cfg.flags & SPI_DEVICE_HALFDUPLEX) || trans_desc->rxlength <= trans_desc->length, "rx length > tx length in full duplex mode", ESP_ERR_INVALID_ARG);
- //check working mode
+ //check working mode
SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && (handle->cfg.flags & SPI_DEVICE_3WIRE)), "incompatible iface params", ESP_ERR_INVALID_ARG);
SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && (!(handle->cfg.flags & SPI_DEVICE_HALFDUPLEX))), "incompatible iface params", ESP_ERR_INVALID_ARG);
SPI_CHECK( !(handle->cfg.flags & SPI_DEVICE_HALFDUPLEX) || handle->host->dma_chan == 0 || !(trans_desc->flags & SPI_TRANS_USE_RXDATA || trans_desc->rx_buffer != NULL)
@@ -717,7 +791,7 @@ esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *
// rx memory assign
if ( trans_desc->flags & SPI_TRANS_USE_RXDATA ) {
trans_buf.buffer_to_rcv = (uint32_t*)&trans_desc->rx_data[0];
- } else {
+ } else {
//if not use RXDATA neither rx_buffer, buffer_to_rcv assigned to NULL
trans_buf.buffer_to_rcv = trans_desc->rx_buffer;
}
@@ -730,12 +804,12 @@ esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *
goto clean_up;
}
}
-
+
const uint32_t *txdata;
// tx memory assign
if ( trans_desc->flags & SPI_TRANS_USE_TXDATA ) {
txdata = (uint32_t*)&trans_desc->tx_data[0];
- } else {
+ } else {
//if not use TXDATA neither tx_buffer, tx data assigned to NULL
txdata = trans_desc->tx_buffer ;
}
@@ -748,11 +822,11 @@ esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *
goto clean_up;
}
memcpy( trans_buf.buffer_to_send, txdata, (trans_desc->length+7)/8 );
- } else {
+ } else {
// else use the original buffer (forced-conversion) or assign to NULL
trans_buf.buffer_to_send = (uint32_t*)txdata;
}
-
+
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_acquire(handle->host->pm_lock);
#endif
@@ -772,24 +846,24 @@ clean_up:
// free malloc-ed buffer (if needed) before return.
if ( (void*)trans_buf.buffer_to_rcv != trans_desc->rx_buffer && (void*)trans_buf.buffer_to_rcv != &trans_desc->rx_data[0] ) {
free( trans_buf.buffer_to_rcv );
- }
+ }
if ( (void*)trans_buf.buffer_to_send!= trans_desc->tx_buffer && (void*)trans_buf.buffer_to_send != &trans_desc->tx_data[0] ) {
free( trans_buf.buffer_to_send );
- }
+ }
assert( ret != ESP_OK );
return ret;
}
-esp_err_t spi_device_get_trans_result(spi_device_handle_t handle, spi_transaction_t **trans_desc, TickType_t ticks_to_wait)
+esp_err_t SPI_MASTER_ATTR spi_device_get_trans_result(spi_device_handle_t handle, spi_transaction_t **trans_desc, TickType_t ticks_to_wait)
{
BaseType_t r;
spi_trans_priv trans_buf;
-
+
SPI_CHECK(handle!=NULL, "invalid dev handle", ESP_ERR_INVALID_ARG);
r=xQueueReceive(handle->ret_queue, (void*)&trans_buf, ticks_to_wait);
if (!r) {
// The memory occupied by rx and tx DMA buffer destroyed only when receiving from the queue (transaction finished).
- // If timeout, wait and retry.
+ // If timeout, wait and retry.
// Every on-flight transaction request occupies internal memory as DMA buffer if needed.
return ESP_ERR_TIMEOUT;
}
@@ -798,12 +872,12 @@ esp_err_t spi_device_get_trans_result(spi_device_handle_t handle, spi_transactio
if ( (void*)trans_buf.buffer_to_send != &(*trans_desc)->tx_data[0] && trans_buf.buffer_to_send != (*trans_desc)->tx_buffer ) {
free( trans_buf.buffer_to_send );
- }
+ }
//copy data from temporary DMA-capable buffer back to IRAM buffer and free the temporary one.
if ( (void*)trans_buf.buffer_to_rcv != &(*trans_desc)->rx_data[0] && trans_buf.buffer_to_rcv != (*trans_desc)->rx_buffer ) {
if ( (*trans_desc)->flags & SPI_TRANS_USE_RXDATA ) {
- memcpy( (uint8_t*)&(*trans_desc)->rx_data[0], trans_buf.buffer_to_rcv, ((*trans_desc)->rxlength+7)/8 );
+ memcpy( (uint8_t*)&(*trans_desc)->rx_data[0], trans_buf.buffer_to_rcv, ((*trans_desc)->rxlength+7)/8 );
} else {
memcpy( (*trans_desc)->rx_buffer, trans_buf.buffer_to_rcv, ((*trans_desc)->rxlength+7)/8 );
}
@@ -814,7 +888,7 @@ esp_err_t spi_device_get_trans_result(spi_device_handle_t handle, spi_transactio
}
//Porcelain to do one blocking transmission.
-esp_err_t spi_device_transmit(spi_device_handle_t handle, spi_transaction_t *trans_desc)
+esp_err_t SPI_MASTER_ATTR spi_device_transmit(spi_device_handle_t handle, spi_transaction_t *trans_desc)
{
esp_err_t ret;
spi_transaction_t *ret_trans;
diff --git a/components/driver/spi_slave.c b/components/driver/spi_slave.c
index 7ee2222e20..7ff89e6c8a 100644
--- a/components/driver/spi_slave.c
+++ b/components/driver/spi_slave.c
@@ -1,4 +1,4 @@
-// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+// Copyright 2015-2018 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.
@@ -15,10 +15,8 @@
#include
#include "driver/spi_common.h"
#include "driver/spi_slave.h"
-#include "soc/gpio_sig_map.h"
-#include "soc/spi_reg.h"
#include "soc/dport_reg.h"
-#include "soc/spi_struct.h"
+#include "soc/spi_periph.h"
#include "rom/ets_sys.h"
#include "esp_types.h"
#include "esp_attr.h"
diff --git a/components/driver/test/test_adc2.c b/components/driver/test/test_adc2.c
index 815f5c79a9..ec6e2ff4f6 100644
--- a/components/driver/test/test_adc2.c
+++ b/components/driver/test/test_adc2.c
@@ -56,8 +56,8 @@ TEST_CASE("adc2 work with wifi","[adc]")
//init wifi
printf("nvs init\n");
esp_err_t r = nvs_flash_init();
- if (r == ESP_ERR_NVS_NO_FREE_PAGES) {
- printf("no free pages, erase..\n");
+ if (r == ESP_ERR_NVS_NO_FREE_PAGES || r == ESP_ERR_NVS_NEW_VERSION_FOUND) {
+ printf("no free pages or nvs version mismatch, erase..\n");
TEST_ESP_OK(nvs_flash_erase());
r = nvs_flash_init();
}
diff --git a/components/driver/test/test_gpio.c b/components/driver/test/test_gpio.c
new file mode 100644
index 0000000000..20962e36f8
--- /dev/null
+++ b/components/driver/test/test_gpio.c
@@ -0,0 +1,593 @@
+/**
+ * About test environment UT_T1_GPIO:
+ * Please connect GPIO18 and GPIO19
+ */
+#include
+#include
+#include "rom/uart.h"
+#include "esp_system.h"
+#include "esp_sleep.h"
+#include "unity.h"
+#include "driver/gpio.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+
+#define WAKE_UP_IGNORE 1 // gpio_wakeup function development is not completed yet, set it deprecated.
+#define GPIO_OUTPUT_IO 18 // default output GPIO
+#define GPIO_INPUT_IO 19 // default input GPIO
+#define GPIO_OUTPUT_MAX GPIO_NUM_34
+static volatile int disable_intr_times = 0; // use this to calculate how many times it go into interrupt
+static volatile int level_intr_times = 0; // use this to get how many times the level interrupt happened
+static volatile int edge_intr_times = 0; // use this to get how many times the edge interrupt happened
+#if !WAKE_UP_IGNORE
+static bool wake_up_result = false; // use this to judge the wake up event happen or not
+#endif
+
+/**
+ * do some initialization operation in this function
+ * @param num: it is the destination GPIO wanted to be initialized
+ *
+ */
+static gpio_config_t init_io(gpio_num_t num)
+{
+ TEST_ASSERT(num < GPIO_OUTPUT_MAX);
+ gpio_config_t io_conf;
+ io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
+ io_conf.mode = GPIO_MODE_OUTPUT;
+ io_conf.pin_bit_mask = (1ULL << num);
+ io_conf.pull_down_en = 0;
+ io_conf.pull_up_en = 0;
+ return io_conf;
+}
+
+// edge interrupt event
+static void gpio_isr_edge_handler(void* arg)
+{
+ uint32_t gpio_num = (uint32_t) arg;
+ ets_printf("GPIO[%d] intr, val: %d\n", gpio_num, gpio_get_level(gpio_num));
+ edge_intr_times++;
+}
+
+// level interrupt event with "gpio_intr_disable"
+static void gpio_isr_level_handler(void* arg)
+{
+ uint32_t gpio_num = (uint32_t) arg;
+ disable_intr_times++;
+ ets_printf("GPIO[%d] intr, val: %d, disable_intr_times = %d\n", gpio_num, gpio_get_level(gpio_num), disable_intr_times);
+ gpio_intr_disable(gpio_num);
+}
+
+// level interrupt event
+static void gpio_isr_level_handler2(void* arg)
+{
+ uint32_t gpio_num = (uint32_t) arg;
+ level_intr_times++;
+ ets_printf("GPIO[%d] intr, val: %d\n", gpio_num, gpio_get_level(gpio_num));
+ if(gpio_get_level(gpio_num)) {
+ gpio_set_level(GPIO_OUTPUT_IO, 0);
+ }else{
+ gpio_set_level(GPIO_OUTPUT_IO, 1);
+ }
+ ets_printf("GPIO[%d] intr, val: %d, level_intr_times = %d\n", GPIO_OUTPUT_IO, gpio_get_level(GPIO_OUTPUT_IO), level_intr_times);
+ ets_printf("GPIO[%d] intr, val: %d, level_intr_times = %d\n", gpio_num, gpio_get_level(gpio_num), level_intr_times);
+}
+
+#if !WAKE_UP_IGNORE
+// get result of waking up or not
+static void sleep_wake_up(void *arg)
+{
+ gpio_config_t io_config = init_io(GPIO_INPUT_IO);
+ io_config.mode = GPIO_MODE_INPUT;
+ gpio_config(&io_config);
+ TEST_ESP_OK(gpio_wakeup_enable(GPIO_INPUT_IO, GPIO_INTR_HIGH_LEVEL));
+ esp_light_sleep_start();
+ wake_up_result = true;
+}
+
+// wake up light sleep event
+static void trigger_wake_up(void *arg)
+{
+ gpio_config_t io_config = init_io(GPIO_OUTPUT_IO);
+ gpio_config(&io_config);
+ gpio_set_level(GPIO_OUTPUT_IO, 0);
+ gpio_install_isr_service(0);
+ gpio_isr_handler_add(GPIO_OUTPUT_IO, gpio_isr_level_handler, (void*) GPIO_INPUT_IO);
+ gpio_set_level(GPIO_OUTPUT_IO, 1);
+ vTaskDelay(100 / portTICK_RATE_MS);
+}
+#endif
+
+static void prompt_to_continue(const char* str)
+{
+ printf("%s , please press \"Enter\" to go on!\n", str);
+ char sign[5] = {0};
+ while(strlen(sign) == 0) {
+ /* Flush anything already in the RX buffer */
+ while(uart_rx_one_char((uint8_t *) sign) == OK) {
+ }
+ /* Read line */
+ UartRxString((uint8_t*) sign, sizeof(sign) - 1);
+ }
+}
+
+static void drive_capability_set_get(gpio_num_t num, gpio_drive_cap_t capability)
+{
+ gpio_config_t pad_io = init_io(num);
+ TEST_ESP_OK(gpio_config(&pad_io));
+ TEST_ASSERT(gpio_set_drive_capability(num, GPIO_DRIVE_CAP_MAX) == ESP_ERR_INVALID_ARG);
+
+ gpio_drive_cap_t cap;
+ TEST_ESP_OK(gpio_set_drive_capability(num, capability));
+ TEST_ESP_OK(gpio_get_drive_capability(num, &cap));
+ TEST_ASSERT_EQUAL_INT(cap, capability);
+}
+
+
+// test the basic configuration function with right parameters and error parameters
+TEST_CASE("GPIO config parameters test", "[gpio]")
+{
+ //error param test
+ //test 41 bit
+ gpio_config_t io_config;
+ io_config.pin_bit_mask = ((uint64_t)1<<(GPIO_NUM_MAX+1));
+ TEST_ASSERT(gpio_config(&io_config) == ESP_ERR_INVALID_ARG);
+
+ // test 0
+ io_config.pin_bit_mask = 0;
+ TEST_ASSERT(gpio_config(&io_config) == ESP_ERR_INVALID_ARG);
+
+ //test 40 bit
+ io_config.pin_bit_mask = ((uint64_t)1< 10) {
+ break;
+ }
+ vTaskDelay(100 / portTICK_RATE_MS);
+ }
+ vTaskDelay(100 / portTICK_RATE_MS);
+ // for falling rdge in GPIO_INTR_ANYEDGE
+ while(1) {
+ level = level - 1;
+ gpio_set_level(GPIO_OUTPUT_IO, level/5);
+ if(level < 0) {
+ break;
+ }
+ vTaskDelay(100 / portTICK_RATE_MS);
+ }
+ vTaskDelay(100 / portTICK_RATE_MS);
+ TEST_ASSERT_EQUAL_INT(edge_intr_times, 2);
+ vTaskDelay(100 / portTICK_RATE_MS);
+ gpio_isr_handler_remove(GPIO_INPUT_IO);
+ gpio_uninstall_isr_service();
+}
+
+TEST_CASE("GPIO input high level trigger, cut the interrupt source exit interrupt test", "[gpio][test_env=UT_T1_GPIO]")
+{
+ level_intr_times=0;
+ gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
+ gpio_config_t input_io = init_io(GPIO_INPUT_IO);
+ input_io.intr_type = GPIO_INTR_POSEDGE;
+ input_io.mode = GPIO_MODE_INPUT;
+ input_io.pull_up_en = 1;
+ TEST_ESP_OK(gpio_config(&output_io));
+ TEST_ESP_OK(gpio_config(&input_io));
+ TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 0));
+
+ gpio_set_intr_type(GPIO_INPUT_IO, GPIO_INTR_HIGH_LEVEL);
+ gpio_install_isr_service(0);
+ gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_level_handler2, (void*) GPIO_INPUT_IO);
+ gpio_set_level(GPIO_OUTPUT_IO, 1);
+ vTaskDelay(100 / portTICK_RATE_MS);
+ TEST_ASSERT_EQUAL_INT_MESSAGE(level_intr_times, 1, "go into high-level interrupt more than once with cur interrupt source way");
+ gpio_isr_handler_remove(GPIO_INPUT_IO);
+ gpio_uninstall_isr_service();
+
+}
+
+TEST_CASE("GPIO low level interrupt test", "[gpio][test_env=UT_T1_GPIO]")
+{
+ disable_intr_times=0;
+ gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
+ gpio_config_t input_io = init_io(GPIO_INPUT_IO);
+ input_io.intr_type = GPIO_INTR_POSEDGE;
+ input_io.mode = GPIO_MODE_INPUT;
+ input_io.pull_up_en = 1;
+ TEST_ESP_OK(gpio_config(&output_io));
+ TEST_ESP_OK(gpio_config(&input_io));
+ TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 1));
+
+ gpio_set_intr_type(GPIO_INPUT_IO, GPIO_INTR_LOW_LEVEL);
+ gpio_install_isr_service(0);
+ gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_level_handler, (void*) GPIO_INPUT_IO);
+ gpio_set_level(GPIO_OUTPUT_IO, 0);
+ printf("get level:%d\n",gpio_get_level(GPIO_INPUT_IO));
+ vTaskDelay(100 / portTICK_RATE_MS);
+ TEST_ASSERT_EQUAL_INT_MESSAGE(disable_intr_times, 1, "go into low-level interrupt more than once with disable way");
+ gpio_isr_handler_remove(GPIO_INPUT_IO);
+ gpio_uninstall_isr_service();
+}
+
+TEST_CASE("GPIO enable and disable interrupt test", "[gpio][test_env=UT_T1_GPIO]")
+{
+ gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
+ gpio_config_t input_io = init_io(GPIO_INPUT_IO);
+ input_io.intr_type = GPIO_INTR_POSEDGE;
+ input_io.mode = GPIO_MODE_INPUT;
+ input_io.pull_up_en = 1;
+ TEST_ESP_OK(gpio_config(&output_io));
+ TEST_ESP_OK(gpio_config(&input_io));
+
+ TEST_ESP_OK(gpio_set_intr_type(GPIO_INPUT_IO, GPIO_INTR_HIGH_LEVEL));
+ TEST_ESP_OK(gpio_install_isr_service(0));
+ TEST_ESP_OK(gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_level_handler, (void*) GPIO_INPUT_IO));
+ TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 1));
+ TEST_ESP_OK(gpio_isr_handler_remove(GPIO_INPUT_IO));
+ TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 0));
+ TEST_ASSERT_EQUAL_INT_MESSAGE(disable_intr_times, 1, "go into high-level interrupt more than once with disable way");
+
+ // not install service now
+ vTaskDelay(100 / portTICK_RATE_MS);
+ TEST_ESP_OK(gpio_intr_disable(GPIO_INPUT_IO));
+ TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 1));
+ TEST_ASSERT_EQUAL_INT_MESSAGE(disable_intr_times, 1, "disable interrupt does not work, still go into interrupt!");
+
+ gpio_uninstall_isr_service(); //uninstall the service
+ TEST_ASSERT(gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_level_handler, (void*) GPIO_INPUT_IO) == ESP_ERR_INVALID_STATE);
+ TEST_ASSERT(gpio_isr_handler_remove(GPIO_INPUT_IO) == ESP_ERR_INVALID_STATE);
+}
+
+// Connect GPIO18 with GPIO19
+// use multimeter to test the voltage, so it is ignored in CI
+TEST_CASE("GPIO set gpio output level test", "[gpio][ignore]")
+{
+ gpio_config_t io_conf;
+ io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
+ io_conf.mode = GPIO_MODE_OUTPUT;
+ io_conf.pin_bit_mask = (1<
+#include
+#include
+#include
+#include
+#include "rom/ets_sys.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/semphr.h"
+#include "freertos/queue.h"
+#include "freertos/xtensa_api.h"
+#include "unity.h"
+#include "soc/ledc_reg.h"
+#include "soc/ledc_struct.h"
+#include "esp_system.h"
+#include "driver/pcnt.h"
+#include "driver/ledc.h"
+#include "driver/gpio.h"
+
+#define PULSE_IO 18
+#define PCNT_INPUT_IO 4
+#define PCNT_CTRL_FLOATING_IO 5
+#define HIGHEST_LIMIT 10000
+#define LOWEST_LIMIT -10000
+
+// use PCNT to test the waveform of LEDC
+static int16_t wave_count(int last_time)
+{
+ int16_t test_counter;
+ pcnt_config_t pcnt_config = {
+ .pulse_gpio_num = PCNT_INPUT_IO,
+ .ctrl_gpio_num = PCNT_CTRL_FLOATING_IO,
+ .channel = PCNT_CHANNEL_0,
+ .unit = PCNT_UNIT_0,
+ .pos_mode = PCNT_COUNT_INC,
+ .neg_mode = PCNT_COUNT_DIS,
+ .lctrl_mode = PCNT_MODE_REVERSE,
+ .hctrl_mode = PCNT_MODE_KEEP,
+ .counter_h_lim = HIGHEST_LIMIT,
+ .counter_l_lim = LOWEST_LIMIT,
+ };
+ TEST_ESP_OK(pcnt_unit_config(&pcnt_config));
+
+ // initialize first
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+
+ vTaskDelay(last_time / portTICK_RATE_MS);
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ return test_counter;
+}
+
+// the PCNT will count the frequency of it
+static void frequency_set_get(ledc_mode_t speed_mode, ledc_timer_t timer, uint32_t freq_hz, int16_t real_freq, int16_t error)
+{
+ int16_t count;
+ TEST_ESP_OK(ledc_set_freq(speed_mode, timer, freq_hz));
+ count = wave_count(1000);
+ TEST_ASSERT_INT16_WITHIN(error, count, real_freq);
+ TEST_ASSERT_EQUAL_INT32(ledc_get_freq(speed_mode, timer), real_freq);
+}
+
+static void timer_frequency_test(ledc_channel_t channel, ledc_timer_bit_t timer_bit, ledc_timer_t timer, ledc_mode_t speed_mode)
+{
+ ledc_channel_config_t ledc_ch_config = {
+ .gpio_num = PULSE_IO,
+ .speed_mode = speed_mode,
+ .channel = channel,
+ .intr_type = LEDC_INTR_DISABLE,
+ .timer_sel = timer,
+ .duty = 4000,
+ };
+ ledc_timer_config_t ledc_time_config = {
+ .speed_mode = speed_mode,
+ .bit_num = timer_bit,
+ .timer_num = timer,
+ .freq_hz = 5000,
+ };
+ TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
+ TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
+
+ if(ledc_ch_config.speed_mode == LEDC_HIGH_SPEED_MODE) {
+ frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 100, 100, 2);
+ frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 5000, 5000, 5);
+ frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 9000, 9025, 5);
+ } else {
+ frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 10, 10, 1);
+// comment it because this is a bug that when ledc in low speed mode, its frequency can't be changed
+// frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 50, 50, 2);
+// frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 100, 100, 2);
+ }
+}
+
+static void timer_duty_set_get(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty)
+{
+ TEST_ESP_OK(ledc_set_duty(speed_mode, channel, duty));
+ TEST_ESP_OK(ledc_update_duty(speed_mode, channel));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ TEST_ASSERT_EQUAL_INT32(ledc_get_duty(speed_mode, channel), duty);
+}
+
+// use logic analyzer to view
+static void timer_duty_test(ledc_channel_t channel, ledc_timer_bit_t timer_bit, ledc_timer_t timer, ledc_mode_t speed_mode)
+{
+ ledc_channel_config_t ledc_ch_config = {
+ .gpio_num = PULSE_IO,
+ .speed_mode = speed_mode,
+ .channel = channel,
+ .intr_type = LEDC_INTR_DISABLE,
+ .timer_sel = timer,
+ .duty = 4000,
+ };
+ ledc_timer_config_t ledc_time_config = {
+ .speed_mode = speed_mode,
+ .bit_num = timer_bit,
+ .timer_num = timer,
+ .freq_hz = 5000,
+ };
+ TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
+ TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
+
+ // duty ratio: (2^duty)/(2^timer_bit)
+ timer_duty_set_get(ledc_ch_config.speed_mode, ledc_ch_config.channel, 0);
+ timer_duty_set_get(ledc_ch_config.speed_mode, ledc_ch_config.channel, 1);
+ timer_duty_set_get(ledc_ch_config.speed_mode, ledc_ch_config.channel, 1 << 12); // 50% duty
+ timer_duty_set_get(ledc_ch_config.speed_mode, ledc_ch_config.channel, (1 << 13) - 1);
+ timer_duty_set_get(ledc_ch_config.speed_mode, ledc_ch_config.channel, (1 << 13) - 2);
+}
+
+TEST_CASE("LEDC error log channel and timer config", "[ledc][test_env=UT_T1_LEDC]")
+{
+ //channel configuration test
+ ledc_channel_config_t ledc_ch_config = {
+ .gpio_num = PULSE_IO,
+ .speed_mode = LEDC_HIGH_SPEED_MODE,
+ .channel = LEDC_CHANNEL_0,
+ .intr_type = LEDC_INTR_DISABLE,
+ .timer_sel = LEDC_TIMER_0,
+ .duty = 4000,
+ };
+
+ // basic right parameter test
+ ledc_channel_config_t temp_ch_config = ledc_ch_config;
+ TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
+
+ // with wrong GPIO using
+ ledc_ch_config.gpio_num = 41;
+ TEST_ASSERT(ledc_channel_config(&ledc_ch_config) == ESP_ERR_INVALID_ARG);
+
+ // with wrong speed
+ ledc_ch_config = temp_ch_config;
+ ledc_ch_config.speed_mode = LEDC_SPEED_MODE_MAX;
+ TEST_ASSERT(ledc_channel_config(&ledc_ch_config) == ESP_ERR_INVALID_ARG);
+
+ // with wrong channel
+ ledc_ch_config = temp_ch_config;
+ ledc_ch_config.channel = LEDC_CHANNEL_MAX;
+ TEST_ASSERT(ledc_channel_config(&ledc_ch_config) == ESP_ERR_INVALID_ARG);
+
+ // with wrong interruption type
+ ledc_ch_config = temp_ch_config;
+ ledc_ch_config.intr_type = 2;
+ TEST_ASSERT_FALSE((void *)ledc_channel_config(&ledc_ch_config));
+
+ // with wrong timer
+ ledc_ch_config = temp_ch_config;
+ ledc_ch_config.timer_sel = 4;
+ TEST_ASSERT(ledc_channel_config(&ledc_ch_config) == ESP_ERR_INVALID_ARG);
+
+ ledc_ch_config = temp_ch_config;
+ ledc_ch_config.duty = 12000;
+ TEST_ASSERT_FALSE((void *)ledc_channel_config(&ledc_ch_config));
+
+ // timer configuration test
+ ledc_timer_config_t ledc_time_config;
+ ledc_time_config.speed_mode = LEDC_HIGH_SPEED_MODE;
+ ledc_time_config.duty_resolution = LEDC_TIMER_13_BIT;
+ ledc_time_config.timer_num = LEDC_TIMER_0;
+ ledc_time_config.freq_hz = 5000;
+
+ ledc_timer_config_t temp_timer_config = ledc_time_config;
+ TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
+
+ ledc_time_config.speed_mode = LEDC_SPEED_MODE_MAX;
+ TEST_ASSERT(ledc_timer_config(&ledc_time_config) == ESP_ERR_INVALID_ARG);
+
+ // wrong duty_resolution
+ ledc_time_config = temp_timer_config;
+ ledc_time_config.duty_resolution = LEDC_TIMER_BIT_MAX;
+ TEST_ASSERT(ledc_timer_config(&ledc_time_config) == ESP_ERR_INVALID_ARG);
+
+ // wrong timer
+ ledc_time_config = temp_timer_config;
+ ledc_time_config.timer_num = 4;
+ TEST_ASSERT(ledc_timer_config(&ledc_time_config) == ESP_ERR_INVALID_ARG);
+
+ uint32_t current_level = LEDC.channel_group[LEDC_HIGH_SPEED_MODE].channel[LEDC_CHANNEL_0].conf0.idle_lv;
+ TEST_ESP_OK(ledc_stop(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, !current_level));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ TEST_ASSERT_EQUAL_INT32( LEDC.channel_group[LEDC_HIGH_SPEED_MODE].channel[LEDC_CHANNEL_0].conf0.idle_lv, !current_level);
+}
+
+TEST_CASE("LEDC normal channel and timer config", "[ledc][test_env=UT_T1_LEDC]")
+{
+ ledc_channel_config_t ledc_ch_config = {
+ .gpio_num = PULSE_IO,
+ .speed_mode = LEDC_HIGH_SPEED_MODE,
+ .channel = LEDC_CHANNEL_0,
+ .intr_type = LEDC_INTR_DISABLE,
+ .timer_sel = LEDC_TIMER_0,
+ .duty = 4000,
+ };
+ ledc_channel_config_t temp_ch_config = ledc_ch_config;
+
+ ledc_timer_config_t ledc_time_config = {
+ .speed_mode = LEDC_HIGH_SPEED_MODE,
+ .bit_num = LEDC_TIMER_13_BIT,
+ .timer_num = LEDC_TIMER_0,
+ .freq_hz = 5000,
+ };
+ ledc_timer_config_t temp_time_config = ledc_time_config;
+
+ // use all kinds of speed mode, channel, timer combination to test all of possible configuration
+ ledc_mode_t speed_mode[2] = {LEDC_HIGH_SPEED_MODE, LEDC_LOW_SPEED_MODE};
+ ledc_channel_t channel_type[8] = {LEDC_CHANNEL_0, LEDC_CHANNEL_1, LEDC_CHANNEL_2, LEDC_CHANNEL_3, LEDC_CHANNEL_4, LEDC_CHANNEL_5, LEDC_CHANNEL_6, LEDC_CHANNEL_7};
+ ledc_timer_t timer_select[4] = {LEDC_TIMER_0, LEDC_TIMER_1, LEDC_TIMER_2, LEDC_TIMER_3};
+
+ for (int i = 0; i < 2; i++) {
+ ledc_ch_config.speed_mode = speed_mode[i];
+ ledc_time_config.speed_mode = speed_mode[i];
+ for (int j = 0; j < 8; j++) {
+ ledc_ch_config.channel = channel_type[j];
+ for (int k = 0; k < 4; k++) {
+ ledc_ch_config.timer_sel = timer_select[k];
+ ledc_time_config.timer_num = timer_select[k];
+ TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
+ TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
+ ledc_ch_config = temp_ch_config;
+ ledc_time_config = temp_time_config;
+ }
+ }
+ }
+}
+
+TEST_CASE("LEDC set and get frequency", "[ledc][test_env=UT_T1_LEDC][timeout=60]")
+{
+ timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_0, LEDC_HIGH_SPEED_MODE);
+ timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_1, LEDC_HIGH_SPEED_MODE);
+ timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_2, LEDC_HIGH_SPEED_MODE);
+ timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_3, LEDC_HIGH_SPEED_MODE);
+// comment it because this is a bug that when ledc in low speed mode, its frequency can't be changed
+// timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_0, LEDC_LOW_SPEED_MODE);
+// timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_1, LEDC_LOW_SPEED_MODE);
+// timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_2, LEDC_LOW_SPEED_MODE);
+// timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_3, LEDC_LOW_SPEED_MODE);
+}
+
+// the duty need to be detected by waveform given by the logic analyzer
+// can't get it directly, so set it "ignore"
+TEST_CASE("LEDC set and get dut(with logic analyzer)", "[ledc][ignore]")
+{
+ ledc_timer_t timer_list[4] = {LEDC_TIMER_0, LEDC_TIMER_1, LEDC_TIMER_2, LEDC_TIMER_3};
+ ledc_mode_t speed_mode_list[2] = {LEDC_HIGH_SPEED_MODE, LEDC_LOW_SPEED_MODE};
+ for(int i=0; i
+#include "freertos/FreeRTOS.h"
+#include "freertos/portmacro.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "driver/periph_ctrl.h"
+#include "driver/gpio.h"
+#include "driver/pcnt.h"
+#include "driver/ledc.h"
+#include "esp_attr.h"
+#include "esp_log.h"
+#include "soc/gpio_sig_map.h"
+#include "unity.h"
+#include "rom/ets_sys.h"
+
+#define PULSE_IO 18
+#define PCNT_INPUT_IO 4
+#define PCNT_CTRL_FLOATING_IO 5
+#define PCNT_CTRL_GND_IO 19
+#define HIGHEST_LIMIT 10
+#define LOWEST_LIMIT 0
+#define MAX_THRESHOLD 5
+#define MIN_THRESHOLD 0
+
+static xQueueHandle pcnt_evt_queue;
+
+typedef struct {
+ int zero_times;
+ int h_limit;
+ int l_limit;
+ int h_threshold;
+ int l_threshold;
+ int filter_time;
+} event_times;
+
+/* use LEDC to produce pulse for PCNT
+ * the frequency of LEDC is 1000, so every second will get 1000 count values
+ * the PCNT count the LEDC pulse
+ * */
+static void produce_pulse(void)
+{
+ ledc_timer_config_t ledc_timer = {
+ .speed_mode = LEDC_HIGH_SPEED_MODE,
+ .timer_num = LEDC_TIMER_1,
+ .duty_resolution = LEDC_TIMER_10_BIT,
+ .freq_hz = 1,
+ };
+ ledc_timer_config(&ledc_timer);
+
+ ledc_channel_config_t ledc_channel = {
+ .speed_mode = LEDC_HIGH_SPEED_MODE,
+ .channel = LEDC_CHANNEL_1,
+ .timer_sel = LEDC_TIMER_1,
+ .intr_type = LEDC_INTR_DISABLE,
+ .gpio_num = PULSE_IO,
+ .duty = 100,
+ .hpoint = 0,
+ };
+ ledc_channel_config(&ledc_channel);
+}
+
+static void IRAM_ATTR pcnt_intr_handler(void *arg)
+{
+ uint32_t intr_status = PCNT.int_st.val;
+ int i;
+ uint32_t status;
+ BaseType_t port_status = pdFALSE;
+
+ for (i = 0; i < PCNT_UNIT_MAX; i++) {
+ if (intr_status & (BIT(i))) {
+ status = PCNT.status_unit[i].val;
+ PCNT.int_clr.val = BIT(i);
+ xQueueSendFromISR(pcnt_evt_queue, &status, &port_status);
+ if (port_status == pdTRUE) {
+ portYIELD_FROM_ISR();
+ }
+ }
+ }
+}
+
+static void event_calculate(event_times* event)
+{
+ int16_t test_counter = 0;
+ int times = 0;
+ BaseType_t port_status;
+ uint32_t status = 0;
+ while (times < 10) {
+ port_status = xQueueReceive(pcnt_evt_queue, &status, 1000 / portTICK_PERIOD_MS);
+ if (port_status == pdTRUE) {
+ event->filter_time++;
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("Current counter value :%d\n", test_counter);
+ if (status & PCNT_STATUS_THRES1_M) {
+ printf("THRES1 EVT\n");
+ event->h_threshold++;
+ }
+ if (status & PCNT_STATUS_THRES0_M) {
+ printf("THRES0 EVT\n");
+ event->l_threshold++;
+ }
+ if (status & PCNT_STATUS_L_LIM_M) {
+ printf("L_LIM EVT\n");
+ event->l_limit++;
+ }
+ if (status & PCNT_STATUS_H_LIM_M) {
+ printf("H_LIM EVT\n");
+ event->h_limit++;
+ }
+ if (status & PCNT_STATUS_ZERO_M) {
+ printf("ZERO EVT\n");
+ event->zero_times++;
+ }
+ } else {
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("Current counter value :%d\n", test_counter);
+ }
+ times++;
+ }
+ printf("%d, %d, %d, %d, %d, %d\n", event->h_threshold, event->l_threshold,
+ event->l_limit, event->h_limit, event->zero_times, event->filter_time);
+}
+
+/*
+ * There exist 2 kind of counting methods: positive and negative counting method
+ * 1. when control IO is high level, PCNT is positive counting mode
+ * 2. when control IO is low level, PCNT is positive negative mode
+ * the positive method standard is as below:
+ * ----------------------------------------------------------------------------------
+ * POS_ MODE | LCTRL_ MODE | HCTRL_ MODE | sig l→h when ctrl=0 | sig l→h when ctrl=1
+ * NEG_ MODE | | | |
+ * ===================================================================================
+ * 1 (inc) | 0 (-) | 0 (-) | Inc ctr | Inc ctr
+ * 2 (dec) | 0 (-) | 0 (-) | Dec ctr | Dec ctr
+ * 0 (-) | x | x | No action | No action
+ * 1 (inc) | 0 (-) | 1 (inv) | Inc ctr | Dec ctr
+ * 1 (inc) | 1 (inv) | 0 (-) | Dec ctr | Inc ctr
+ * 2 (dec) | 0 (-) | 1 (inv) | Dec ctr | Inc ctr
+ * 1 (inc) | 0 (-) | 2 (dis) | Inc ctr | No action
+ * 1 (inc) | 2 (dis) | 0 (-) | No action | Inc ctr
+ * -----------------------------------------------------------------------------------
+ * */
+
+static void count_mode_test(gpio_num_t ctl_io)
+{
+ int16_t test_counter;
+ //produce pulse, 100HZ
+ ledc_timer_config_t ledc_timer = {
+ .speed_mode = LEDC_HIGH_SPEED_MODE,
+ .timer_num = LEDC_TIMER_1,
+ .duty_resolution = LEDC_TIMER_10_BIT,
+ .freq_hz = 100,
+ };
+ ledc_timer_config(&ledc_timer);
+
+ ledc_channel_config_t ledc_channel = {
+ .speed_mode = LEDC_HIGH_SPEED_MODE,
+ .channel = LEDC_CHANNEL_1,
+ .timer_sel = LEDC_TIMER_1,
+ .intr_type = LEDC_INTR_DISABLE,
+ .gpio_num = PULSE_IO,
+ .duty = 100,
+ .hpoint = 0,
+ };
+ ledc_channel_config(&ledc_channel);
+
+ pcnt_config_t pcnt_config = {
+ .pulse_gpio_num = PCNT_INPUT_IO,
+ .ctrl_gpio_num = ctl_io,
+ .channel = PCNT_CHANNEL_0,
+ .unit = PCNT_UNIT_0,
+ .pos_mode = PCNT_COUNT_INC,
+ .neg_mode = PCNT_COUNT_DIS,
+ .lctrl_mode = PCNT_MODE_REVERSE,
+ .hctrl_mode = PCNT_MODE_KEEP,
+ .counter_h_lim = 101,
+ .counter_l_lim = -101,
+ };
+ TEST_ESP_OK(pcnt_unit_config(&pcnt_config));
+ int16_t result1[8] = {100, -100, 0, -100, 100, 100, 0, 100};
+ int16_t result2[8] = {100, -100, 0, 100, -100, -100, 100, 0};
+ int16_t *result;
+ if (gpio_get_level(pcnt_config.ctrl_gpio_num)) {
+ result = result1;
+ } else {
+ result = result2;
+ }
+
+ // 1, 0, 0, 0
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0,
+ PCNT_COUNT_INC, PCNT_COUNT_DIS,
+ PCNT_MODE_KEEP, PCNT_MODE_KEEP));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("value: %d\n", test_counter);
+ TEST_ASSERT_INT16_WITHIN(1, test_counter, result[0]);
+
+ //2, 0, 0, 0
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0,
+ PCNT_COUNT_DEC, PCNT_COUNT_DIS,
+ PCNT_MODE_KEEP, PCNT_MODE_KEEP));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("value: %d\n", test_counter);
+ TEST_ASSERT_INT16_WITHIN(1, test_counter, result[1]);
+
+ //0,0,0,0
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0,
+ PCNT_COUNT_DIS, PCNT_COUNT_DIS,
+ PCNT_MODE_KEEP, PCNT_MODE_KEEP));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("value: %d\n", test_counter);
+ TEST_ASSERT_INT16_WITHIN(1, test_counter, result[2]);
+
+ //1,0,1,0
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0,
+ PCNT_COUNT_INC, PCNT_COUNT_DIS,
+ PCNT_MODE_REVERSE, PCNT_MODE_KEEP));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("value: %d\n", test_counter);
+ TEST_ASSERT_INT16_WITHIN(1, test_counter, result[3]);
+
+ //1,0,0,1
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0,
+ PCNT_COUNT_INC, PCNT_COUNT_DIS,
+ PCNT_MODE_KEEP, PCNT_MODE_REVERSE));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("value: %d\n", test_counter);
+ TEST_ASSERT_INT16_WITHIN(1, test_counter, result[4]);
+
+ //2,0,0,1
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0,
+ PCNT_COUNT_DEC, PCNT_COUNT_DIS,
+ PCNT_MODE_REVERSE, PCNT_MODE_KEEP));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("value: %d\n", test_counter);
+ TEST_ASSERT_INT16_WITHIN(1, test_counter, result[5]);
+
+ //1,0,2,0
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0,
+ PCNT_COUNT_INC, PCNT_COUNT_DIS,
+ PCNT_MODE_DISABLE, PCNT_MODE_KEEP));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("value: %d\n", test_counter);
+ TEST_ASSERT_INT16_WITHIN(1, test_counter, result[6]);
+
+ //1,0,0,2
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_set_mode(PCNT_UNIT_0, PCNT_CHANNEL_0,
+ PCNT_COUNT_INC, PCNT_COUNT_DIS,
+ PCNT_MODE_KEEP, PCNT_MODE_DISABLE));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("value: %d\n", test_counter);
+ TEST_ASSERT_INT16_WITHIN(1, test_counter, result[7]);
+}
+
+// test PCNT basic configuration
+TEST_CASE("PCNT test config", "[pcnt][test_env=UT_T1_PCNT]")
+{
+ pcnt_config_t pcnt_config = {
+ .pulse_gpio_num = PCNT_INPUT_IO,
+ .ctrl_gpio_num = PCNT_CTRL_FLOATING_IO,
+ .channel = PCNT_CHANNEL_0,
+ .unit = PCNT_UNIT_0,
+ .pos_mode = PCNT_COUNT_INC,
+ .neg_mode = PCNT_COUNT_DIS,
+ .lctrl_mode = PCNT_MODE_REVERSE,
+ .hctrl_mode = PCNT_MODE_KEEP,
+ .counter_h_lim = 100,
+ .counter_l_lim = 0,
+ };
+ // basic configuration
+ pcnt_config_t temp_pcnt_config = pcnt_config;
+ TEST_ESP_OK(pcnt_unit_config(&pcnt_config));
+
+ // test 8 units, from 0-7
+ pcnt_config = temp_pcnt_config;
+ pcnt_config.unit = PCNT_UNIT_MAX;
+ TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config));
+ for (int i = 0; i <= 7; i++) {
+ pcnt_config.unit = i;
+ TEST_ESP_OK(pcnt_unit_config(&pcnt_config));
+ }
+
+ // test channels
+ pcnt_config = temp_pcnt_config;
+ pcnt_config.channel = PCNT_CHANNEL_MAX;
+ TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config));
+ pcnt_config = temp_pcnt_config;
+ pcnt_config.pulse_gpio_num = -1;
+ TEST_ESP_OK(pcnt_unit_config(&pcnt_config));
+
+ pcnt_config = temp_pcnt_config;
+ pcnt_config.pulse_gpio_num = 41;
+ TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config));
+
+ // test pulse_gpio_num and ctrl_gpio_num is the same
+ pcnt_config = temp_pcnt_config;
+ pcnt_config.pulse_gpio_num = PCNT_INPUT_IO;
+ pcnt_config.ctrl_gpio_num = PCNT_INPUT_IO;
+ TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config));
+
+ pcnt_config = temp_pcnt_config;
+ pcnt_config.pos_mode = PCNT_COUNT_MAX;
+ TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config));
+
+ pcnt_config = temp_pcnt_config;
+ pcnt_config.hctrl_mode = PCNT_MODE_MAX;
+ TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config));
+
+ pcnt_config = temp_pcnt_config;
+ pcnt_config.lctrl_mode = PCNT_MODE_MAX;
+ TEST_ASSERT_NOT_NULL((void *)pcnt_unit_config(&pcnt_config));
+}
+
+/* PCNT basic property:
+ * 1. pause counter
+ * 2. resume counter
+ * 3. clear counter
+ * 4. check the counter value*/
+TEST_CASE("PCNT basic function test", "[pcnt][test_env=UT_T1_PCNT]")
+{
+ int16_t test_counter;
+ int16_t time = 0;
+ int clear_count = 0;
+ int resume_count = 0;
+ int temp_value = 0;
+ pcnt_config_t pcnt_config = {
+ .pulse_gpio_num = PCNT_INPUT_IO,
+ .ctrl_gpio_num = PCNT_CTRL_FLOATING_IO,
+ .channel = PCNT_CHANNEL_0,
+ .unit = PCNT_UNIT_0,
+ .pos_mode = PCNT_COUNT_INC,
+ .neg_mode = PCNT_COUNT_DIS,
+ .lctrl_mode = PCNT_MODE_REVERSE,
+ .hctrl_mode = PCNT_MODE_KEEP,
+ .counter_h_lim = 10,
+ .counter_l_lim = -10,
+ };
+ TEST_ESP_OK(pcnt_unit_config(&pcnt_config));
+
+ // use LEDC to produce the pulse, then the PCNT to count it
+ produce_pulse();
+
+ // initialize first, the initail value should be 0
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ TEST_ASSERT_EQUAL_INT16(test_counter, 0);
+
+ // resume the PCNT
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ TEST_ASSERT_EQUAL_INT16(test_counter, 0);
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ TEST_ASSERT_EQUAL_INT16(test_counter, 0);
+
+ //count now
+ while (time != 10) {
+ vTaskDelay(1001 / portTICK_RATE_MS); // in case of can't wait to get counter(edge effect)
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("COUNT: %d\n", test_counter);
+ TEST_ASSERT_NOT_EQUAL(test_counter, temp_value);
+ temp_value = test_counter;
+
+ if (test_counter == 5 || test_counter == -5) {
+ //test clear
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ TEST_ASSERT_EQUAL_INT16(test_counter, 0);
+ clear_count++;
+ }
+ if (test_counter == 0) {
+ //test pause
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("PAUSE: %d\n", test_counter);
+ TEST_ASSERT_EQUAL_INT16(test_counter, 0);
+
+ // test resume
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
+ printf("RESUME: %d\n", test_counter);
+ TEST_ASSERT_EQUAL_INT16(test_counter, (gpio_get_level(PCNT_CTRL_FLOATING_IO) > 0) ? (1) : -1);
+ resume_count++;
+ }
+ time++;
+ }
+ TEST_ASSERT_EQUAL_INT16(clear_count, 2);
+ TEST_ASSERT_EQUAL_INT16(resume_count, 2);
+}
+
+/**
+ * there are 4 situations will be tested:
+ * 1. set event to interrupt triggered
+ * 2. disable interrupt to stop triggering interrupt
+ * 3. enable interrupt to interrupt triggered again
+ * 4. disable event to stop triggering interrupt
+ *
+ * PCNT interrupt type:
+ * 1. PCNT_EVT_THRES_1
+ * 2. PCNT_EVT_THRES_0
+ * 3. PCNT_EVT_ZERO
+ * 4. PCNT_EVT_H_LIM
+ * 5. PCNT_EVT_L_LIM
+ * */
+TEST_CASE("PCNT interrupt method test(control IO is high)", "[pcnt][test_env=UT_T1_PCNT][timeout=120]")
+{
+ pcnt_config_t config = {
+ .pulse_gpio_num = PCNT_INPUT_IO,
+ .ctrl_gpio_num = PCNT_CTRL_FLOATING_IO,
+ .channel = PCNT_CHANNEL_0,
+ .unit = PCNT_UNIT_0,
+ .pos_mode = PCNT_COUNT_INC,
+ .neg_mode = PCNT_COUNT_DIS,
+ .lctrl_mode = PCNT_MODE_REVERSE,
+ .hctrl_mode = PCNT_MODE_KEEP,
+ .counter_h_lim = 5,
+ .counter_l_lim = 0,
+ };
+ TEST_ESP_OK(pcnt_unit_config(&config));
+ produce_pulse();
+
+ event_times event = {
+ .zero_times = 0,
+ .h_limit = 0,
+ .l_limit = 0,
+ .h_threshold = 0,
+ .l_threshold = 0,
+ .filter_time = 0,
+ };
+
+ //interrupt set
+ TEST_ESP_OK(pcnt_set_filter_value(PCNT_UNIT_0, 2));
+ TEST_ESP_OK(pcnt_filter_enable(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_set_event_value(PCNT_UNIT_0, PCNT_EVT_THRES_1, 4)); // when arrive to max threshold trigger
+ TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_1));
+ TEST_ESP_OK(pcnt_set_event_value(PCNT_UNIT_0, PCNT_EVT_THRES_0, 1)); // when arrive to minimum threshold trigger
+ TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_0));
+ TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_ZERO));
+ TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_H_LIM)); // when arrive to max limit trigger
+ TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_L_LIM)); // when arrive to minimum limit trigger
+
+ // to initialize for PCNT
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+
+ TEST_ESP_OK(pcnt_isr_register(pcnt_intr_handler, NULL, 0, NULL));
+ TEST_ESP_OK(pcnt_intr_enable(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+
+ pcnt_evt_queue = xQueueCreate(10, sizeof(uint32_t));
+
+ // test event
+ event_calculate(&event);
+ TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 2);
+ TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 2);
+ TEST_ASSERT(event.l_limit == 0);
+ TEST_ASSERT_INT_WITHIN(2, event.h_limit, 2);
+ TEST_ASSERT_INT_WITHIN(2, event.zero_times, 2);
+ TEST_ASSERT_INT_WITHIN(3, event.filter_time, 4);
+
+ // test interrupt disable
+ TEST_ESP_OK(pcnt_intr_disable(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ // for the original control io disable interrupt status
+ event_calculate(&event);
+ TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 2);
+ TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 2);
+ TEST_ASSERT(event.l_limit == 0);
+ TEST_ASSERT_INT_WITHIN(2, event.h_limit, 2);
+ TEST_ASSERT_INT_WITHIN(2, event.zero_times, 2);
+ TEST_ASSERT_INT_WITHIN(3, event.filter_time, 4);
+
+ // enable the intr
+ TEST_ESP_OK(pcnt_intr_enable(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ event_calculate(&event);
+ TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 4);
+ TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 4);
+ TEST_ASSERT(event.l_limit == 0);
+ TEST_ASSERT_INT_WITHIN(2, event.h_limit, 4);
+ TEST_ASSERT_INT_WITHIN(2, event.zero_times, 4);
+ TEST_ASSERT_INT_WITHIN(3, event.filter_time, 10);
+
+ // disable part of events
+ TEST_ESP_OK(pcnt_event_disable(PCNT_UNIT_0, PCNT_EVT_ZERO));
+ TEST_ESP_OK(pcnt_event_disable(PCNT_UNIT_0, PCNT_EVT_L_LIM));
+ TEST_ESP_OK(pcnt_event_disable(PCNT_UNIT_0, PCNT_EVT_THRES_0));
+ event_calculate(&event);
+ TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 5);
+ TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 4);
+ TEST_ASSERT(event.l_limit == 0);
+ TEST_ASSERT_INT_WITHIN(2, event.h_limit, 6);
+ TEST_ASSERT_INT_WITHIN(2, event.zero_times, 4);
+ TEST_ASSERT_INT_WITHIN(3, event.filter_time, 14);
+
+ pcnt_isr_service_uninstall();
+}
+
+TEST_CASE("PCNT interrupt method test(control IO is low)", "[pcnt][test_env=UT_T1_PCNT][timeout=120]")
+{
+ pcnt_config_t config = {
+ .pulse_gpio_num = PCNT_INPUT_IO,
+ .ctrl_gpio_num = PCNT_CTRL_GND_IO,
+ .channel = PCNT_CHANNEL_0,
+ .unit = PCNT_UNIT_0,
+ .pos_mode = PCNT_COUNT_INC,
+ .neg_mode = PCNT_COUNT_DIS,
+ .lctrl_mode = PCNT_MODE_REVERSE,
+ .hctrl_mode = PCNT_MODE_KEEP,
+ .counter_h_lim = 0,
+ .counter_l_lim = -5,
+ };
+
+ TEST_ESP_OK(pcnt_unit_config(&config));
+ produce_pulse();
+
+ event_times event = {
+ .zero_times = 0,
+ .h_limit = 0,
+ .l_limit = 0,
+ .h_threshold = 0,
+ .l_threshold = 0,
+ .filter_time = 0,
+ };
+
+ //interrupt set
+ TEST_ESP_OK(pcnt_set_filter_value(PCNT_UNIT_0, 2));
+ TEST_ESP_OK(pcnt_filter_enable(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_set_event_value(PCNT_UNIT_0, PCNT_EVT_THRES_1, -4)); // when arrive to max threshold trigger
+ TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_1));
+ TEST_ESP_OK(pcnt_set_event_value(PCNT_UNIT_0, PCNT_EVT_THRES_0, 0)); // when arrive to minimum threshold trigger
+ TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_0));
+ TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_ZERO));
+ TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_H_LIM)); // when arrive to max limit trigger
+ TEST_ESP_OK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_L_LIM)); // when arrive to minimum limit trigger
+
+ // to initialize for PCNT
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+
+ TEST_ESP_OK(pcnt_isr_register(pcnt_intr_handler, NULL, 0, NULL));
+ TEST_ESP_OK(pcnt_intr_enable(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+
+ pcnt_evt_queue = xQueueCreate(10, sizeof(uint32_t));
+
+ // test event
+ event_calculate(&event);
+ TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 1);
+ TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 1);
+ TEST_ASSERT_INT_WITHIN(2, event.l_limit, 1);
+ TEST_ASSERT_INT_WITHIN(2, event.h_limit, 0);
+ TEST_ASSERT_INT_WITHIN(2, event.zero_times, 1);
+ TEST_ASSERT_INT_WITHIN(2, event.filter_time, 2);
+
+ // test interrupt disable
+ TEST_ESP_OK(pcnt_intr_disable(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ // for the original control io disable interrupt status
+ event_calculate(&event);
+ TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 1);
+ TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 1);
+ TEST_ASSERT_INT_WITHIN(2, event.l_limit, 1);
+ TEST_ASSERT_INT_WITHIN(2, event.h_limit, 0);
+ TEST_ASSERT_INT_WITHIN(2, event.zero_times, 1);
+ TEST_ASSERT_INT_WITHIN(2, event.filter_time, 2);
+
+ // enable the intr
+ pcnt_unit_config(&config);
+ TEST_ESP_OK(pcnt_intr_enable(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
+ TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
+ event_calculate(&event);
+ TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 2);
+ TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 3);
+ TEST_ASSERT_INT_WITHIN(2, event.l_limit, 2);
+ TEST_ASSERT_INT_WITHIN(2, event.h_limit, 0);
+ TEST_ASSERT_INT_WITHIN(2, event.zero_times, 2);
+ TEST_ASSERT_INT_WITHIN(2, event.filter_time, 6);
+
+ // disable part of events
+ TEST_ESP_OK(pcnt_event_disable(PCNT_UNIT_0, PCNT_EVT_ZERO));
+ TEST_ESP_OK(pcnt_event_disable(PCNT_UNIT_0, PCNT_EVT_L_LIM));
+ TEST_ESP_OK(pcnt_event_disable(PCNT_UNIT_0, PCNT_EVT_THRES_0));
+ event_calculate(&event);
+ TEST_ASSERT_INT_WITHIN(2, event.h_threshold, 4);
+ TEST_ASSERT_INT_WITHIN(2, event.l_threshold, 3);
+ TEST_ASSERT_INT_WITHIN(2, event.l_limit, 2);
+ TEST_ASSERT_INT_WITHIN(2, event.h_limit, 0);
+ TEST_ASSERT_INT_WITHIN(2, event.zero_times, 2);
+ TEST_ASSERT_INT_WITHIN(2, event.filter_time, 8);
+
+ pcnt_isr_service_uninstall();
+}
+
+TEST_CASE("PCNT counting mode test", "[pcnt][test_env=UT_T1_PCNT]")
+{
+ printf("PCNT mode test for positive count\n");
+ count_mode_test(PCNT_CTRL_FLOATING_IO);
+ printf("PCNT mode test for negative count\n");
+ count_mode_test(PCNT_CTRL_GND_IO);
+}
diff --git a/components/driver/test/test_rmt.c b/components/driver/test/test_rmt.c
new file mode 100644
index 0000000000..de9937e3aa
--- /dev/null
+++ b/components/driver/test/test_rmt.c
@@ -0,0 +1,682 @@
+/**
+ * please connect GPIO18 to GPIO19
+ */
+#include "stdio.h"
+#include
+#include "driver/rmt.h"
+#include "unity.h"
+#include "test_utils.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "freertos/semphr.h"
+#include "esp_err.h"
+#include "esp_log.h"
+#include "driver/periph_ctrl.h"
+#include "soc/rmt_reg.h"
+
+static const char* TAG = "RMT";
+
+
+#define RMT_RX_ACTIVE_LEVEL 1 /*!< Data bit is active high for self test mode */
+#define RMT_TX_CARRIER_EN 0 /*!< Disable carrier for self test mode */
+
+#define RMT_TX_CHANNEL 1 /*!< RMT channel for transmitter */
+#define RMT_TX_GPIO_NUM 18 /*!< GPIO number for transmitter signal */
+#define RMT_RX_CHANNEL 0 /*!< RMT channel for receiver */
+#define RMT_RX_GPIO_NUM 19 /*!< GPIO number for receiver */
+#define RMT_CLK_DIV 100 /*!< RMT counter clock divider */
+#define RMT_TICK_10_US (80000000/RMT_CLK_DIV/100000) /*!< RMT counter value for 10 us.(Source clock is APB clock) */
+
+#define HEADER_HIGH_US 9000 /*!< NEC protocol header: positive 9ms */
+#define HEADER_LOW_US 4500 /*!< NEC protocol header: negative 4.5ms*/
+#define BIT_ONE_HIGH_US 560 /*!< NEC protocol data bit 1: positive 0.56ms */
+#define BIT_ONE_LOW_US (2250-BIT_ONE_HIGH_US) /*!< NEC protocol data bit 1: negative 1.69ms */
+#define BIT_ZERO_HIGH_US 560 /*!< NEC protocol data bit 0: positive 0.56ms */
+#define BIT_ZERO_LOW_US (1120-BIT_ZERO_HIGH_US) /*!< NEC protocol data bit 0: negative 0.56ms */
+#define BIT_END 560 /*!< NEC protocol end: positive 0.56ms */
+#define BIT_MARGIN 20 /*!< NEC parse margin time */
+
+#define ITEM_DURATION(d) ((d & 0x7fff)*10/RMT_TICK_10_US) /*!< Parse duration time from memory register value */
+#define DATA_ITEM_NUM 34 /*!< NEC code item number: header + 32bit data + end */
+#define RMT_TX_DATA_NUM 100 /*!< NEC tx test data number */
+#define RMT_ITEM32_TIMEOUT_US 9500 /*!< RMT receiver timeout value(us) */
+
+/**
+ * @brief Build register value of waveform for NEC one data bit
+ */
+static inline void fill_item_level(rmt_item32_t* item, int high_us, int low_us)
+{
+ item->level0 = 1;
+ item->duration0 = (high_us) / 10 * RMT_TICK_10_US;
+ item->level1 = 0;
+ item->duration1 = (low_us) / 10 * RMT_TICK_10_US;
+}
+
+/**
+ * @brief Generate NEC header value: active 9ms + negative 4.5ms
+ */
+static void fill_item_header(rmt_item32_t* item)
+{
+ fill_item_level(item, HEADER_HIGH_US, HEADER_LOW_US);
+}
+
+/*
+ * @brief Generate NEC data bit 1: positive 0.56ms + negative 1.69ms
+ */
+static void fill_item_bit_one(rmt_item32_t* item)
+{
+ fill_item_level(item, BIT_ONE_HIGH_US, BIT_ONE_LOW_US);
+}
+
+/**
+ * @brief Generate NEC data bit 0: positive 0.56ms + negative 0.56ms
+ */
+static void fill_item_bit_zero(rmt_item32_t* item)
+{
+ fill_item_level(item, BIT_ZERO_HIGH_US, BIT_ZERO_LOW_US);
+}
+
+/**
+ * @brief Generate NEC end signal: positive 0.56ms
+ */
+static void fill_item_end(rmt_item32_t* item)
+{
+ fill_item_level(item, BIT_END, 0x7fff);
+}
+
+/**
+ * @brief Check whether duration is around target_us
+ */
+inline bool check_in_range(int duration_ticks, int target_us, int margin_us)
+{
+ if(( ITEM_DURATION(duration_ticks) < (target_us + margin_us))
+ && ( ITEM_DURATION(duration_ticks) > (target_us - margin_us))) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * @brief Check whether this value represents an NEC header
+ */
+static bool header_if(rmt_item32_t* item)
+{
+ if((item->level0 == RMT_RX_ACTIVE_LEVEL && item->level1 != RMT_RX_ACTIVE_LEVEL)
+ && check_in_range(item->duration0, HEADER_HIGH_US, BIT_MARGIN)
+ && check_in_range(item->duration1, HEADER_LOW_US, BIT_MARGIN)) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Check whether this value represents an NEC data bit 1
+ */
+static bool bit_one_if(rmt_item32_t* item)
+{
+ if((item->level0 == RMT_RX_ACTIVE_LEVEL && item->level1 != RMT_RX_ACTIVE_LEVEL)
+ && check_in_range(item->duration0, BIT_ONE_HIGH_US, BIT_MARGIN)
+ && check_in_range(item->duration1, BIT_ONE_LOW_US, BIT_MARGIN)) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Check whether this value represents an NEC data bit 0
+ */
+static bool bit_zero_if(rmt_item32_t* item)
+{
+ if((item->level0 == RMT_RX_ACTIVE_LEVEL && item->level1 != RMT_RX_ACTIVE_LEVEL)
+ && check_in_range(item->duration0, BIT_ZERO_HIGH_US, BIT_MARGIN)
+ && check_in_range(item->duration1, BIT_ZERO_LOW_US, BIT_MARGIN)) {
+ return true;
+ }
+ return false;
+}
+
+
+/**
+ * @brief Parse NEC 32 bit waveform to address and command.
+ */
+static int parse_items(rmt_item32_t* item, int item_num, uint16_t* addr, uint16_t* data)
+{
+ int w_len = item_num;
+ if(w_len < DATA_ITEM_NUM) {
+ return -1;
+ }
+ int i = 0, j = 0;
+ if(!header_if(item++)) {
+ return -1;
+ }
+ uint16_t addr_t = 0;
+ for(j = 0; j < 16; j++) {
+ if(bit_one_if(item)) {
+ addr_t |= (1 << j);
+ } else if(bit_zero_if(item)) {
+ addr_t |= (0 << j);
+ } else {
+ return -1;
+ }
+ item++;
+ i++;
+ }
+ uint16_t data_t = 0;
+ for(j = 0; j < 16; j++) {
+ if(bit_one_if(item)) {
+ data_t |= (1 << j);
+ } else if(bit_zero_if(item)) {
+ data_t |= (0 << j);
+ } else {
+ return -1;
+ }
+ item++;
+ i++;
+ }
+ *addr = addr_t;
+ *data = data_t;
+ return i;
+}
+
+/**
+ * @brief Build NEC 32bit waveform.
+ */
+static int build_items(int channel, rmt_item32_t* item, int item_num, uint16_t addr, uint16_t cmd_data)
+{
+ int i = 0, j = 0;
+ if(item_num < DATA_ITEM_NUM) {
+ return -1;
+ }
+ fill_item_header(item++);
+ i++;
+ for(j = 0; j < 16; j++) {
+ if(addr & 0x1) {
+ fill_item_bit_one(item);
+ } else {
+ fill_item_bit_zero(item);
+ }
+ item++;
+ i++;
+ addr >>= 1;
+ }
+ for(j = 0; j < 16; j++) {
+ if(cmd_data & 0x1) {
+ fill_item_bit_one(item);
+ } else {
+ fill_item_bit_zero(item);
+ }
+ item++;
+ i++;
+ cmd_data >>= 1;
+ }
+ fill_item_end(item);
+ i++;
+ return i;
+}
+
+static void set_tx_data(int tx_channel, uint16_t cmd, uint16_t addr, int item_num, rmt_item32_t* item, int offset)
+{
+ while(1) {
+ int i = build_items(tx_channel, item + offset, item_num - offset, ((~addr) << 8) | addr, cmd);
+ printf("cmd :%d\n", cmd);
+ if(i < 0) {
+ break;
+ }
+ cmd++;
+ addr++;
+ offset += i;
+ }
+}
+
+static int get_rx_data(RingbufHandle_t rb)
+{
+ uint16_t tmp = 0;
+ while(rb) {
+ size_t rx_size = 0;
+ rmt_item32_t* rx_item = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 1000);
+ if(rx_item) {
+ uint16_t rmt_addr;
+ uint16_t rmt_cmd;
+ int rx_offset = 0;
+ while(1) {
+ int res = parse_items(rx_item + rx_offset, rx_size / 4 - rx_offset, &rmt_addr, &rmt_cmd);
+ if(res > 0) {
+ rx_offset += res + 1;
+ ESP_LOGI(TAG, "RMT RCV --- addr: 0x%04x cmd: 0x%04x", rmt_addr, rmt_cmd);
+ TEST_ASSERT(rmt_cmd == tmp);
+ tmp++;
+ } else {
+ break;
+ }
+ }
+ vRingbufferReturnItem(rb, (void*) rx_item);
+ } else {
+ break;
+ }
+ }
+ return tmp;
+}
+
+/**
+ * @brief RMT transmitter initialization
+ */
+static void tx_init()
+{
+ // the sender once it send something, its frq is 38kHz, and the duty cycle is 50%
+ rmt_tx_config_t tx_cfg = {
+ .loop_en = false,
+ .carrier_duty_percent = 50,
+ .carrier_freq_hz = 38000,
+ .carrier_level = 1,
+ .carrier_en = RMT_TX_CARRIER_EN,
+ .idle_level = 0,
+ .idle_output_en = true,
+ };
+ rmt_config_t rmt_tx = {
+ .channel = RMT_TX_CHANNEL,
+ .gpio_num = RMT_TX_GPIO_NUM,
+ .mem_block_num = 1,
+ .clk_div = RMT_CLK_DIV,
+ .tx_config = tx_cfg,
+ .rmt_mode = 0,
+ };
+ rmt_config(&rmt_tx);
+ rmt_driver_install(rmt_tx.channel, 0, 0);
+}
+
+/**
+ * @brief RMT receiver initialization
+ */
+static void rx_init()
+{
+ rmt_rx_config_t rx_cfg = {
+ .filter_en = true,
+ .filter_ticks_thresh = 100,
+ .idle_threshold = RMT_ITEM32_TIMEOUT_US / 10 * (RMT_TICK_10_US),
+ };
+ rmt_config_t rmt_rx = {
+ .channel = RMT_RX_CHANNEL,
+ .gpio_num = RMT_RX_GPIO_NUM,
+ .clk_div = RMT_CLK_DIV,
+ .mem_block_num = 1,
+ .rmt_mode = RMT_MODE_RX,
+ .rx_config = rx_cfg,
+ };
+ rmt_config(&rmt_rx);
+ rmt_driver_install(rmt_rx.channel, (sizeof(rmt_item32_t) * DATA_ITEM_NUM * (RMT_TX_DATA_NUM+6)), 0);
+}
+
+TEST_CASE("RMT init config", "[rmt][test_env=UT_T1_RMT]")
+{
+ // tx settings
+ rmt_tx_config_t tx_cfg = {
+ .loop_en = false,
+ .carrier_duty_percent = 50,
+ .carrier_freq_hz = 38000,
+ .carrier_level = 1,
+ .carrier_en = RMT_TX_CARRIER_EN,
+ .idle_level = 0,
+ .idle_output_en = true,
+ };
+ rmt_config_t rmt_tx = {
+ .channel = RMT_TX_CHANNEL,
+ .gpio_num = RMT_TX_GPIO_NUM,
+ .mem_block_num = 1,
+ .clk_div = RMT_CLK_DIV,
+ .tx_config = tx_cfg,
+ };
+ TEST_ESP_OK(rmt_config(&rmt_tx));
+ TEST_ESP_OK(rmt_driver_install(rmt_tx.channel, 0, 0));
+ TEST_ESP_OK(rmt_driver_uninstall(rmt_tx.channel));
+
+ //rx settings
+ rmt_rx_config_t rx_cfg = {
+ .filter_en = true,
+ .filter_ticks_thresh = 100,
+ .idle_threshold = RMT_ITEM32_TIMEOUT_US / 10 * (RMT_TICK_10_US),
+ };
+ rmt_config_t rmt_rx = {
+ .channel = RMT_RX_CHANNEL,
+ .gpio_num = RMT_RX_GPIO_NUM,
+ .clk_div = RMT_CLK_DIV,
+ .mem_block_num = 1,
+ .rmt_mode = RMT_MODE_RX,
+ .rx_config = rx_cfg,
+ };
+ TEST_ESP_OK(rmt_config(&rmt_rx));
+ TEST_ESP_OK(rmt_driver_install(rmt_rx.channel, 1000, 0));
+ TEST_ESP_OK(rmt_driver_uninstall(rmt_rx.channel));
+
+ //error param setting
+ rmt_config_t temp_rmt_rx1 = {
+ .channel = 2,
+ .gpio_num = 15,
+ .clk_div = RMT_CLK_DIV,
+ .mem_block_num = 1,
+ .rmt_mode = RMT_MODE_RX,
+ .rx_config = rx_cfg,
+ };
+ rmt_config_t temp_rmt_rx2 = temp_rmt_rx1;
+
+ temp_rmt_rx2.clk_div = 0; // only invalid parameter to test
+ TEST_ASSERT(rmt_config(&temp_rmt_rx2) == ESP_ERR_INVALID_ARG);
+
+ temp_rmt_rx2 = temp_rmt_rx1;
+ temp_rmt_rx2.channel = RMT_CHANNEL_MAX;
+ TEST_ASSERT(rmt_config(&temp_rmt_rx2) == ESP_ERR_INVALID_ARG);
+
+ temp_rmt_rx2 = temp_rmt_rx1;
+ temp_rmt_rx2.channel = 2;
+ temp_rmt_rx2.mem_block_num = 8;
+ TEST_ASSERT(rmt_config(&temp_rmt_rx2) == ESP_ERR_INVALID_ARG);
+}
+
+TEST_CASE("RMT init set function", "[rmt][test_env=UT_T1_RMT]")
+{
+ rmt_channel_t channel = 7;
+ TEST_ESP_OK(rmt_set_pin(channel, RMT_MODE_RX, RMT_RX_GPIO_NUM));
+ TEST_ESP_OK(rmt_set_clk_div(channel, RMT_CLK_DIV*2));
+ TEST_ESP_OK(rmt_set_mem_block_num(channel, 1));
+ TEST_ESP_OK(rmt_set_rx_filter(channel, 1, 100));
+ TEST_ESP_OK(rmt_set_rx_idle_thresh(channel, RMT_ITEM32_TIMEOUT_US / 10 * (RMT_TICK_10_US)*2));
+ TEST_ESP_OK(rmt_driver_install(channel, 0, 0));
+ TEST_ESP_OK(rmt_driver_uninstall(channel));
+}
+
+// need to make sure its phenomenon by logic analyzer, can't run in CI
+TEST_CASE("RMT clock devider, clock source set(logic analyzer)", "[rmt][ignore]")
+{
+ uint8_t div_cnt;
+ rmt_source_clk_t src_clk;
+ rmt_config_t rmt_tx;
+ rmt_tx.channel = RMT_TX_CHANNEL;
+ rmt_tx.mem_block_num = 1;
+ rmt_tx.gpio_num = RMT_TX_GPIO_NUM;
+ rmt_tx.clk_div = RMT_CLK_DIV;
+ rmt_tx.tx_config.loop_en = true;
+ rmt_tx.tx_config.carrier_duty_percent = 50;
+ rmt_tx.tx_config.carrier_freq_hz = 38000;
+ rmt_tx.tx_config.carrier_level = 1;
+ rmt_tx.tx_config.carrier_en = RMT_TX_CARRIER_EN;
+ rmt_tx.tx_config.idle_level = 0;
+ rmt_tx.tx_config.idle_output_en = true;
+ rmt_tx.rmt_mode = RMT_MODE_TX;
+
+ TEST_ESP_OK(rmt_config(&rmt_tx));
+ TEST_ESP_OK(rmt_get_clk_div(RMT_TX_CHANNEL, &div_cnt));
+ TEST_ESP_OK(rmt_driver_install(rmt_tx.channel, 0, 0));
+ TEST_ASSERT_EQUAL_UINT8(div_cnt, RMT_CLK_DIV);
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
+
+ // reset it and check it
+ TEST_ESP_OK(rmt_set_clk_div(RMT_TX_CHANNEL, 160));
+ TEST_ESP_OK(rmt_get_clk_div(RMT_TX_CHANNEL, &div_cnt));
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
+
+ TEST_ESP_OK(rmt_set_source_clk(RMT_TX_CHANNEL, RMT_BASECLK_APB));
+ TEST_ESP_OK(rmt_get_source_clk(RMT_TX_CHANNEL, &src_clk));
+ TEST_ASSERT_EQUAL_UINT8(div_cnt, 160);
+ TEST_ASSERT_EQUAL_INT(src_clk, RMT_BASECLK_APB);
+ TEST_ESP_OK(rmt_driver_uninstall(rmt_tx.channel));
+}
+
+TEST_CASE("RMT rx set and get properties", "[rmt][test_env=UT_T1_RMT]")
+{
+ rmt_channel_t channel = RMT_RX_CHANNEL;
+ uint8_t memNum;
+ uint8_t div_cnt;
+ uint16_t idleThreshold;
+ rmt_mem_owner_t owner;
+
+ rx_init();
+
+ TEST_ESP_OK(rmt_get_clk_div(channel, &div_cnt));
+ TEST_ESP_OK(rmt_get_mem_block_num(channel, &memNum));
+ TEST_ESP_OK(rmt_get_rx_idle_thresh(channel, &idleThreshold));
+ TEST_ESP_OK(rmt_get_memory_owner(channel, &owner));
+
+ TEST_ASSERT_EQUAL_UINT8(div_cnt, RMT_CLK_DIV);
+ TEST_ASSERT_EQUAL_UINT8(memNum, 1);
+ TEST_ASSERT_EQUAL_UINT16(idleThreshold, RMT_ITEM32_TIMEOUT_US / 10 * (RMT_TICK_10_US));
+ TEST_ASSERT_EQUAL_INT(owner, RMT_MEM_OWNER_RX);
+
+ //eRR
+ TEST_ESP_OK(rmt_set_pin(channel, RMT_MODE_RX, 22));
+ TEST_ESP_OK(rmt_set_clk_div(channel, RMT_CLK_DIV*2));
+ TEST_ESP_OK(rmt_set_mem_block_num(channel, 2));
+ TEST_ESP_OK(rmt_set_rx_filter(channel, 1, 100));
+ TEST_ESP_OK(rmt_set_rx_idle_thresh(channel, RMT_ITEM32_TIMEOUT_US / 10 * (RMT_TICK_10_US)*2));
+ TEST_ESP_OK(rmt_set_memory_owner(channel, RMT_MEM_OWNER_RX));
+
+ TEST_ESP_OK(rmt_get_clk_div(channel, &div_cnt));
+ TEST_ESP_OK(rmt_get_mem_block_num(channel, &memNum));
+ TEST_ESP_OK(rmt_get_rx_idle_thresh(channel, &idleThreshold));
+ TEST_ESP_OK(rmt_get_memory_owner(channel, &owner));
+
+ TEST_ASSERT_EQUAL_UINT8(div_cnt, RMT_CLK_DIV*2);
+ TEST_ASSERT_EQUAL_UINT8(memNum, 2);
+ TEST_ASSERT_EQUAL_UINT16(idleThreshold, RMT_ITEM32_TIMEOUT_US / 10 * (RMT_TICK_10_US)*2);
+ TEST_ASSERT_EQUAL_INT(owner, RMT_MEM_OWNER_RX);
+
+ TEST_ESP_OK(rmt_driver_uninstall(channel));
+}
+
+TEST_CASE("RMT tx set and get properties", "[rmt][test_env=UT_T1_RMT]")
+{
+ rmt_channel_t channel = RMT_TX_CHANNEL;
+ uint8_t memNum;
+ uint8_t div_cnt;
+ bool loop_en;
+ rmt_mem_owner_t owner;
+
+ tx_init();
+ TEST_ESP_OK(rmt_get_clk_div(channel, &div_cnt));
+ TEST_ESP_OK(rmt_get_mem_block_num(channel, &memNum));
+ TEST_ESP_OK(rmt_get_tx_loop_mode(channel, &loop_en));
+ TEST_ESP_OK(rmt_get_memory_owner(channel, &owner));
+
+ TEST_ASSERT_EQUAL_INT8(loop_en, 0);
+ TEST_ASSERT_EQUAL_UINT8(div_cnt, RMT_CLK_DIV);
+ TEST_ASSERT_EQUAL_UINT8(memNum, 1);
+ TEST_ASSERT_EQUAL_INT(owner, RMT_MEM_OWNER_TX);
+
+ //reset by "set"
+ TEST_ESP_OK(rmt_set_pin(channel, RMT_MODE_TX, RMT_TX_GPIO_NUM));
+ TEST_ESP_OK(rmt_set_clk_div(channel, RMT_CLK_DIV*2));
+ TEST_ESP_OK(rmt_set_mem_block_num(channel, 2));
+ TEST_ESP_OK(rmt_set_tx_loop_mode(channel, 1));
+ TEST_ESP_OK(rmt_set_tx_carrier(channel, 0, 1, 0, 1));
+ TEST_ESP_OK(rmt_set_idle_level(channel, 1, 0));
+ TEST_ESP_OK(rmt_set_memory_owner(channel, RMT_MEM_OWNER_TX));
+
+ TEST_ESP_OK(rmt_get_clk_div(channel, &div_cnt));
+ TEST_ESP_OK(rmt_get_mem_block_num(channel, &memNum));
+ TEST_ESP_OK(rmt_get_tx_loop_mode(channel, &loop_en));
+ TEST_ESP_OK(rmt_get_memory_owner(channel, &owner));
+
+ TEST_ASSERT_EQUAL_INT8(loop_en, 1);
+ TEST_ASSERT_EQUAL_UINT8(div_cnt, RMT_CLK_DIV*2);
+ TEST_ASSERT_EQUAL_UINT8(memNum, 2);
+ TEST_ASSERT_EQUAL_INT(owner, RMT_MEM_OWNER_TX);
+
+ rmt_item32_t items[1];
+ items[0].duration0 = 300 / 10 * RMT_TICK_10_US; //300us
+ items[0].level0 = 1;
+ items[0].duration1 = 0;
+ items[0].level1 = 0;
+ for(int i=0; i<100; i++) {
+ TEST_ESP_OK(rmt_write_items(RMT_TX_CHANNEL, items,
+ 1, /* Number of items */
+ 1 /* wait till done */));
+ vTaskDelay(10/portTICK_PERIOD_MS); //every 10ms to write the item
+ }
+ TEST_ESP_OK(rmt_driver_uninstall(channel));
+}
+
+TEST_CASE("RMT memory test", "[rmt][test_env=UT_T1_RMT]")
+{
+ rmt_config_t rmt_rx;
+ rmt_rx.channel = RMT_RX_CHANNEL;
+ rmt_rx.gpio_num = RMT_RX_GPIO_NUM;
+ rmt_rx.clk_div = RMT_CLK_DIV;
+ rmt_rx.mem_block_num = 1;
+ rmt_rx.rmt_mode = RMT_MODE_RX;
+ rmt_rx.rx_config.filter_en = true;
+ rmt_rx.rx_config.filter_ticks_thresh = 100;
+ rmt_rx.rx_config.idle_threshold = RMT_ITEM32_TIMEOUT_US / 10 * (RMT_TICK_10_US);
+ TEST_ESP_OK(rmt_config(&rmt_rx));
+
+ for(int i = 0; i<100; i++) {
+ TEST_ESP_OK(rmt_driver_install(rmt_rx.channel, 1000, 0));
+ TEST_ESP_OK(rmt_driver_uninstall(rmt_rx.channel));
+ }
+}
+
+TEST_CASE("RMT send waveform(logic analyzer)", "[rmt][test_env=UT_T1_RMT][ignore]")
+{
+ tx_init();
+ rmt_item32_t items[1];
+ items[0].duration0 = 300 / 10 * RMT_TICK_10_US; //300us
+ items[0].level0 = 1;
+ for(int i=0; i<500; i++) {
+ TEST_ESP_OK(rmt_write_items(RMT_TX_CHANNEL, items,
+ 1, /* Number of items */
+ 1 /* wait till done */));
+ vTaskDelay(10/portTICK_PERIOD_MS); //every 10ms to write the item
+ }
+ TEST_ESP_OK(rmt_driver_uninstall(RMT_TX_CHANNEL));
+}
+
+TEST_CASE("RMT basic TX and RX", "[rmt][test_env=UT_T1_RMT]")
+{
+ tx_init();
+ int tx_channel = RMT_TX_CHANNEL;
+ uint16_t cmd = 0x0;
+ uint16_t addr = 0x11;
+ int tx_num = RMT_TX_DATA_NUM;
+ ESP_LOGI(TAG, "RMT TX DATA");
+ size_t size = (sizeof(rmt_item32_t) * DATA_ITEM_NUM * tx_num);
+ rmt_item32_t* item = (rmt_item32_t*) malloc(size);
+ int item_num = DATA_ITEM_NUM * tx_num;
+ memset((void*) item, 0, size);
+ int offset = 0;
+
+ int rx_channel = RMT_RX_CHANNEL;
+ rx_init();
+ RingbufHandle_t rb = NULL;
+ rmt_get_ringbuf_handle(rx_channel, &rb);
+ rmt_rx_start(rx_channel, 1);
+ // send data
+ set_tx_data(tx_channel, cmd, addr, item_num, item, offset);
+ rmt_write_items(tx_channel, item, item_num, 1);
+ free(item);
+ // receive data
+ uint16_t tmp = get_rx_data(rb);
+ TEST_ASSERT(tmp == 100);
+ TEST_ESP_OK(rmt_driver_uninstall(RMT_TX_CHANNEL));
+ TEST_ESP_OK(rmt_driver_uninstall(RMT_RX_CHANNEL));
+}
+
+TEST_CASE("RMT TX write item not wait", "[rmt][test_env=UT_T1_RMT]")
+{
+ tx_init();
+ int tx_channel = RMT_TX_CHANNEL;
+ uint16_t cmd = 0x0;
+ uint16_t addr = 0x11;
+ int tx_num = RMT_TX_DATA_NUM;
+ ESP_LOGI(TAG, "RMT TX DATA");
+ size_t size = (sizeof(rmt_item32_t) * DATA_ITEM_NUM * tx_num);
+ rmt_item32_t* item = (rmt_item32_t*) malloc(size);
+ int item_num = DATA_ITEM_NUM * tx_num;
+ memset((void*) item, 0, size);
+ int offset = 0;
+
+ int rx_channel = RMT_RX_CHANNEL;
+ rx_init();
+ RingbufHandle_t rb = NULL;
+ rmt_get_ringbuf_handle(rx_channel, &rb);
+ rmt_rx_start(rx_channel, 1);
+
+ // send data
+ set_tx_data(tx_channel, cmd, addr, item_num, item, offset);
+ rmt_write_items(tx_channel, item, item_num, 0);
+ free(item);
+
+ // receive data
+ uint16_t tmp = get_rx_data(rb);
+ TEST_ASSERT(tmp < 100);
+ TEST_ESP_OK(rmt_driver_uninstall(RMT_TX_CHANNEL));
+ TEST_ESP_OK(rmt_driver_uninstall(RMT_RX_CHANNEL));
+}
+
+TEST_CASE("RMT TX write item wait some ticks", "[rmt][test_env=UT_T1_RMT]")
+{
+ tx_init();
+ int tx_channel = RMT_TX_CHANNEL;
+ uint16_t cmd = 0x0;
+ uint16_t addr = 0x11;
+ int tx_num = RMT_TX_DATA_NUM;
+ ESP_LOGI(TAG, "RMT TX DATA");
+ size_t size = (sizeof(rmt_item32_t) * DATA_ITEM_NUM * tx_num);
+ rmt_item32_t* item = (rmt_item32_t*) malloc(size);
+ int item_num = DATA_ITEM_NUM * tx_num;
+ memset((void*) item, 0, size);
+ int offset = 0;
+
+ int rx_channel = RMT_RX_CHANNEL;
+ rx_init();
+ RingbufHandle_t rb = NULL;
+ rmt_get_ringbuf_handle(rx_channel, &rb);
+ rmt_rx_start(rx_channel, 1);
+
+ // send data
+ set_tx_data(tx_channel, cmd, addr, item_num, item, offset);
+ rmt_write_items(tx_channel, item, item_num, 0);
+ rmt_wait_tx_done(tx_channel, portMAX_DELAY);
+ free(item);
+
+ // receive data
+ uint16_t tmp = get_rx_data(rb);
+ TEST_ASSERT(tmp == 100);
+ TEST_ESP_OK(rmt_driver_uninstall(RMT_TX_CHANNEL));
+ TEST_ESP_OK(rmt_driver_uninstall(RMT_RX_CHANNEL));
+}
+
+TEST_CASE("RMT TX stop test", "[rmt][test_env=UT_T1_RMT]")
+{
+ int rx_channel = RMT_RX_CHANNEL;
+ rx_init();
+ RingbufHandle_t rb = NULL;
+ rmt_get_ringbuf_handle(rx_channel, &rb);
+ rmt_rx_start(rx_channel, 1);
+
+ vTaskDelay(10);
+ tx_init();
+ int tx_channel = RMT_TX_CHANNEL;
+ int tx_num = RMT_TX_DATA_NUM;
+
+ ESP_LOGI(TAG, "RMT TX DATA");
+ size_t size = (sizeof(rmt_item32_t) * DATA_ITEM_NUM * tx_num);
+ rmt_item32_t* item = (rmt_item32_t*) malloc(size);
+ int item_num = DATA_ITEM_NUM * tx_num;
+ memset((void*) item, 0, size);
+ int offset = 0;
+ uint16_t cmd = 0x0;
+ uint16_t addr = 0x11;
+
+ // send data
+ set_tx_data(tx_channel, cmd, addr, item_num, item, offset);
+ rmt_write_items(tx_channel, item, item_num, 0);
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
+ rmt_tx_stop(tx_channel);
+ free(item);
+
+ // receive data
+ uint16_t tmp = get_rx_data(rb);
+ TEST_ASSERT(tmp < 100);
+
+ TEST_ESP_OK(rmt_driver_uninstall(RMT_TX_CHANNEL));
+ TEST_ESP_OK(rmt_driver_uninstall(RMT_RX_CHANNEL));
+}
diff --git a/components/driver/test/test_sigmadelta.c b/components/driver/test/test_sigmadelta.c
new file mode 100644
index 0000000000..fa1088186c
--- /dev/null
+++ b/components/driver/test/test_sigmadelta.c
@@ -0,0 +1,87 @@
+/*
+ * Sigamadelta Test:
+ * 1. basic configuration test
+ * 2. pin, duty, prescale test
+ */
+#include "unity.h"
+#include "test_utils.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "driver/sigmadelta.h"
+
+TEST_CASE("SigmaDelta config test", "[sigma_delta]")
+{
+ sigmadelta_config_t sigmadelta_cfg = {
+ .channel = SIGMADELTA_CHANNEL_0,
+ .sigmadelta_prescale = 80,
+ .sigmadelta_duty = 45,
+ .sigmadelta_gpio = 4,
+ };
+ TEST_ESP_OK(sigmadelta_config(&sigmadelta_cfg));
+
+ sigmadelta_cfg.channel = SIGMADELTA_CHANNEL_1;
+ TEST_ESP_OK(sigmadelta_config(&sigmadelta_cfg));
+
+ sigmadelta_cfg.channel = SIGMADELTA_CHANNEL_2;
+ TEST_ESP_OK(sigmadelta_config(&sigmadelta_cfg));
+
+ sigmadelta_cfg.channel = SIGMADELTA_CHANNEL_3;
+ TEST_ESP_OK(sigmadelta_config(&sigmadelta_cfg));
+
+ sigmadelta_cfg.channel = SIGMADELTA_CHANNEL_4;
+ TEST_ESP_OK(sigmadelta_config(&sigmadelta_cfg));
+
+ sigmadelta_cfg.channel = SIGMADELTA_CHANNEL_5;
+ TEST_ESP_OK(sigmadelta_config(&sigmadelta_cfg));
+
+ sigmadelta_cfg.channel = SIGMADELTA_CHANNEL_6;
+ TEST_ESP_OK(sigmadelta_config(&sigmadelta_cfg));
+
+ sigmadelta_cfg.channel = SIGMADELTA_CHANNEL_7;
+ TEST_ESP_OK(sigmadelta_config(&sigmadelta_cfg));
+
+ //ERROR PARAM
+ sigmadelta_cfg.channel = SIGMADELTA_CHANNEL_MAX;
+ TEST_ASSERT(sigmadelta_config(&sigmadelta_cfg) == ESP_ERR_INVALID_ARG);
+
+}
+
+// connect GPIO4 with LED positive pin, and the GND pin connect LED negative pin
+// logic analyzer help also to see the wave form(more standard and accurate)
+// can't test it in CI, ignore
+TEST_CASE("SigmaDelta pin, duty, prescale set", "[sigma_delta][ignore]")
+{
+ sigmadelta_config_t sigmadelta_cfg = {
+ .channel = SIGMADELTA_CHANNEL_0,
+ .sigmadelta_prescale = 80,
+ .sigmadelta_duty = 0,
+ .sigmadelta_gpio = 4,
+ };
+ TEST_ESP_OK(sigmadelta_config(&sigmadelta_cfg));
+
+ int8_t duty = 0;
+ int inc = 1;
+ for(int i=0; i<1000; i++) {
+ sigmadelta_set_duty(SIGMADELTA_CHANNEL_0, duty);
+ vTaskDelay(10 / portTICK_PERIOD_MS);
+
+ duty += inc;
+ if (duty == 127 || duty == -127) {
+ inc = (-1) * inc;
+ }
+ }
+
+ TEST_ESP_OK(sigmadelta_set_prescale(SIGMADELTA_CHANNEL_0, 200));
+ for(int i=0; i<1000; i++) {
+ sigmadelta_set_duty(SIGMADELTA_CHANNEL_0, duty);
+ vTaskDelay(10 / portTICK_PERIOD_MS);
+
+ duty += inc;
+ if (duty == 127 || duty == -127) {
+ inc = (-1) * inc;
+ }
+ }
+
+ TEST_ESP_OK(sigmadelta_set_pin(SIGMADELTA_CHANNEL_0, 5));
+ vTaskDelay(3000 / portTICK_PERIOD_MS);
+}
diff --git a/components/driver/test/test_spi_master.c b/components/driver/test/test_spi_master.c
index da6d5a5961..8887d5cefc 100644
--- a/components/driver/test/test_spi_master.c
+++ b/components/driver/test/test_spi_master.c
@@ -17,14 +17,43 @@
#include "driver/spi_master.h"
#include "driver/spi_slave.h"
#include "soc/dport_reg.h"
-#include "soc/spi_reg.h"
-#include "soc/spi_struct.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
+#include "soc/spi_periph.h"
#include "freertos/ringbuf.h"
+#include "soc/gpio_periph.h"
+#include "sdkconfig.h"
const static char TAG[] = "test_spi";
+#define SPI_BUS_TEST_DEFAULT_CONFIG() {\
+ .miso_io_num=PIN_NUM_MISO, \
+ .mosi_io_num=PIN_NUM_MOSI,\
+ .sclk_io_num=PIN_NUM_CLK,\
+ .quadwp_io_num=-1,\
+ .quadhd_io_num=-1\
+}
+
+#define SPI_DEVICE_TEST_DEFAULT_CONFIG() {\
+ .clock_speed_hz=10*1000*1000,\
+ .mode=0,\
+ .spics_io_num=PIN_NUM_CS,\
+ .queue_size=16,\
+ .pre_cb=NULL, \
+ .cs_ena_pretrans = 0,\
+ .cs_ena_posttrans = 0,\
+ .input_delay_ns = 62.5,\
+}
+
+#define FUNC_SPI 1
+#define FUNC_GPIO 2
+
+void gpio_output_sel(uint32_t gpio_num, int func, uint32_t signal_idx)
+{
+ PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], func);
+ GPIO.func_out_sel_cfg[gpio_num].func_sel=signal_idx;
+}
+
static void check_spi_pre_n_for(int clk, int pre, int n)
{
esp_err_t ret;
@@ -90,7 +119,7 @@ TEST_CASE("SPI Master clockdiv calculation routines", "[spi]")
static spi_device_handle_t setup_spi_bus(int clkspeed, bool dma) {
spi_bus_config_t buscfg={
- .mosi_io_num=4,
+ .mosi_io_num=26,
.miso_io_num=26,
.sclk_io_num=25,
.quadwp_io_num=-1,
@@ -109,22 +138,24 @@ static spi_device_handle_t setup_spi_bus(int clkspeed, bool dma) {
};
esp_err_t ret;
spi_device_handle_t handle;
- printf("THIS TEST NEEDS A JUMPER BETWEEN IO4 AND IO26\n");
ret=spi_bus_initialize(HSPI_HOST, &buscfg, dma?1:0);
TEST_ASSERT(ret==ESP_OK);
ret=spi_bus_add_device(HSPI_HOST, &devcfg, &handle);
TEST_ASSERT(ret==ESP_OK);
+ //connect MOSI to two devices breaks the output, fix it.
+ gpio_output_sel(26, FUNC_GPIO, HSPID_OUT_IDX);
printf("Bus/dev inited.\n");
return handle;
}
-static void spi_test(spi_device_handle_t handle, int num_bytes) {
+static int spi_test(spi_device_handle_t handle, int num_bytes) {
esp_err_t ret;
int x;
+ bool success = true;
srand(num_bytes);
- char *sendbuf=heap_caps_malloc(num_bytes, MALLOC_CAP_DMA);
- char *recvbuf=heap_caps_malloc(num_bytes, MALLOC_CAP_DMA);
+ char *sendbuf=heap_caps_malloc((num_bytes+3)&(~3), MALLOC_CAP_DMA);
+ char *recvbuf=heap_caps_malloc((num_bytes+3)&(~3), MALLOC_CAP_DMA);
for (x=0; xmosi_io_num, GPIO_PULLUP_ENABLE);
+ gpio_set_pull_mode(cfg->sclk_io_num, GPIO_PULLUP_ENABLE);
+ gpio_set_pull_mode(spics_io_num, GPIO_PULLUP_ENABLE);
}
typedef struct {
@@ -705,10 +724,12 @@ typedef struct {
typedef struct {
uint32_t len;
+ uint8_t* tx_start;
uint8_t data[1];
} slave_rxdata_t;
typedef struct {
+ spi_host_device_t spi;
RingbufHandle_t data_received;
QueueHandle_t data_to_send;
} spi_slave_task_context_t;
@@ -723,6 +744,7 @@ esp_err_t init_slave_context(spi_slave_task_context_t *context)
if ( context->data_received == NULL ) {
return ESP_ERR_NO_MEM;
}
+ context->spi=VSPI_HOST;
return ESP_OK;
}
@@ -736,12 +758,16 @@ void deinit_slave_context(spi_slave_task_context_t *context)
context->data_received = NULL;
}
+/* The task requires a queue and a ringbuf, which should be initialized before task starts.
+ Send ``slave_txdata_t`` to the queue to make the task send data;
+ the task returns data got to the ringbuf, which should have sufficient size.
+*/
static void task_slave(void* arg)
{
spi_slave_task_context_t* context = (spi_slave_task_context_t*) arg;
QueueHandle_t queue = context->data_to_send;
RingbufHandle_t ringbuf = context->data_received;
- uint8_t recvbuf[320+4];
+ uint8_t recvbuf[320+8];
slave_txdata_t txdata;
ESP_LOGI( SLAVE_TAG, "slave up" );
@@ -749,18 +775,19 @@ static void task_slave(void* arg)
while( 1 ) {
xQueueReceive( queue, &txdata, portMAX_DELAY );
- ESP_LOGI( "test", "received: %p", txdata.start );
+ ESP_LOGI( "test", "to send: %p", txdata.start );
spi_slave_transaction_t t = {};
t.length = txdata.len;
t.tx_buffer = txdata.start;
- t.rx_buffer = recvbuf+4;
+ t.rx_buffer = recvbuf+8;
//loop until trans_len != 0 to skip glitches
do {
- TEST_ESP_OK( spi_slave_transmit( VSPI_HOST, &t, portMAX_DELAY ) );
+ TEST_ESP_OK( spi_slave_transmit( context->spi, &t, portMAX_DELAY ) );
} while ( t.trans_len == 0 );
- *(uint32_t*)recvbuf = t.trans_len;
+ memcpy(recvbuf, &t.trans_len, sizeof(uint32_t));
+ *(uint8_t**)(recvbuf+4) = txdata.start;
ESP_LOGI( SLAVE_TAG, "received: %d", t.trans_len );
- xRingbufferSend( ringbuf, recvbuf, 4+(t.trans_len+7)/8, portMAX_DELAY );
+ xRingbufferSend( ringbuf, recvbuf, 8+(t.trans_len+7)/8, portMAX_DELAY );
}
}
@@ -775,16 +802,33 @@ TEST_CASE("SPI master variable cmd & addr test","[spi]")
TEST_ASSERT( err == ESP_OK );
spi_device_handle_t spi;
- //initial master, mode 0, 1MHz
- master_init( &spi, 0, 1*1000*1000 );
- //initial slave, mode 0, no dma
- slave_init(0, 0);
- //do internal connection
- int_connect( PIN_NUM_MOSI, HSPID_OUT_IDX, VSPIQ_IN_IDX );
- int_connect( PIN_NUM_MISO, VSPIQ_OUT_IDX, HSPID_IN_IDX );
- int_connect( PIN_NUM_CS, HSPICS0_OUT_IDX, VSPICS0_IN_IDX );
- int_connect( PIN_NUM_CLK, HSPICLK_OUT_IDX, VSPICLK_IN_IDX );
+ //initial master, mode 0, 1MHz
+ spi_bus_config_t buscfg=SPI_BUS_TEST_DEFAULT_CONFIG();
+ TEST_ESP_OK(spi_bus_initialize(HSPI_HOST, &buscfg, 1));
+ spi_device_interface_config_t devcfg=SPI_DEVICE_TEST_DEFAULT_CONFIG();
+ devcfg.clock_speed_hz = 1*1000*1000; //currently only up to 4MHz for internel connect
+ devcfg.mode = 0;
+ devcfg.cs_ena_posttrans = 2;
+ TEST_ESP_OK(spi_bus_add_device(HSPI_HOST, &devcfg, &spi));
+
+ //initial slave, mode 0, no dma
+ int dma_chan = 0;
+ int slave_mode = 0;
+ spi_bus_config_t slv_buscfg=SPI_BUS_TEST_DEFAULT_CONFIG();
+ spi_slave_interface_config_t slvcfg=SPI_SLAVE_TEST_DEFAULT_CONFIG();
+ slvcfg.mode = slave_mode;
+ //Enable pull-ups on SPI lines so we don't detect rogue pulses when no master is connected.
+ slave_pull_up(&buscfg, slvcfg.spics_io_num);
+ //Initialize SPI slave interface
+ TEST_ESP_OK( spi_slave_initialize(VSPI_HOST, &slv_buscfg, &slvcfg, dma_chan) );
+
+
+ //connecting pins to two peripherals breaks the output, fix it.
+ gpio_output_sel(PIN_NUM_MOSI, FUNC_GPIO, HSPID_OUT_IDX);
+ gpio_output_sel(PIN_NUM_MISO, FUNC_GPIO, VSPIQ_OUT_IDX);
+ gpio_output_sel(PIN_NUM_CS, FUNC_GPIO, HSPICS0_OUT_IDX);
+ gpio_output_sel(PIN_NUM_CLK, FUNC_GPIO, HSPICLK_OUT_IDX);
TaskHandle_t handle_slave;
xTaskCreate( task_slave, "spi_slave", 4096, &slave_context, 0, &handle_slave);
@@ -871,7 +915,7 @@ TEST_CASE("SPI master variable cmd & addr test","[spi]")
handle_slave = 0;
deinit_slave_context(&slave_context);
-
+
TEST_ASSERT(spi_slave_free(VSPI_HOST) == ESP_OK);
TEST_ASSERT(spi_bus_remove_device(spi) == ESP_OK);
@@ -879,7 +923,355 @@ TEST_CASE("SPI master variable cmd & addr test","[spi]")
ESP_LOGI(MASTER_TAG, "test passed.");
}
+/********************************************************************************
+ * Test Timing By Internal Connections
+ ********************************************************************************/
+typedef enum {
+ FULL_DUPLEX = 0,
+ HALF_DUPLEX_MISO = 1,
+ HALF_DUPLEX_MOSI = 2,
+} spi_dup_t;
+static int timing_speed_array[]={/**/
+ SPI_MASTER_FREQ_8M ,
+ SPI_MASTER_FREQ_9M ,
+ SPI_MASTER_FREQ_10M,
+ SPI_MASTER_FREQ_11M,
+ SPI_MASTER_FREQ_13M,
+ SPI_MASTER_FREQ_16M,
+ SPI_MASTER_FREQ_20M,
+ SPI_MASTER_FREQ_26M,
+ SPI_MASTER_FREQ_40M,
+ SPI_MASTER_FREQ_80M,
+};
+
+typedef struct {
+ uint8_t master_rxbuf[320];
+ spi_transaction_t master_trans[16];
+ TaskHandle_t handle_slave;
+ spi_slave_task_context_t slave_context;
+ slave_txdata_t slave_trans[16];
+} timing_context_t;
+
+void master_print_data(spi_transaction_t *t, spi_dup_t dup)
+{
+ if (t->tx_buffer) {
+ ESP_LOG_BUFFER_HEX( "master tx", t->tx_buffer, t->length/8 );
+ } else {
+ ESP_LOGI( "master tx", "no data" );
+ }
+
+ int rxlength;
+ if (dup!=HALF_DUPLEX_MISO) {
+ rxlength = t->length/8;
+ } else {
+ rxlength = t->rxlength/8;
+ }
+ if (t->rx_buffer) {
+ ESP_LOG_BUFFER_HEX( "master rx", t->rx_buffer, rxlength );
+ } else {
+ ESP_LOGI( "master rx", "no data" );
+ }
+}
+
+void slave_print_data(slave_rxdata_t *t)
+{
+ int rcv_len = (t->len+7)/8;
+ ESP_LOGI(SLAVE_TAG, "trans_len: %d", t->len);
+ ESP_LOG_BUFFER_HEX( "slave tx", t->tx_start, rcv_len);
+ ESP_LOG_BUFFER_HEX( "slave rx", t->data, rcv_len);
+}
+
+esp_err_t check_data(spi_transaction_t *t, spi_dup_t dup, slave_rxdata_t *slave_t)
+{
+ int length;
+ if (dup!=HALF_DUPLEX_MISO) {
+ length = t->length;
+ } else {
+ length = t->rxlength;
+ }
+ TEST_ASSERT(length!=0);
+
+ //currently the rcv_len can be in range of [t->length-1, t->length+3]
+ uint32_t rcv_len = slave_t->len;
+ TEST_ASSERT(rcv_len >= length-1 && rcv_len <= length+3);
+
+ //the timing speed is temporarily only for master
+ if (dup!=HALF_DUPLEX_MISO) {
+// TEST_ASSERT_EQUAL_HEX8_ARRAY(t->tx_buffer, slave_t->data, (t->length+7)/8);
+ }
+ if (dup!=HALF_DUPLEX_MOSI) {
+ TEST_ASSERT_EQUAL_HEX8_ARRAY(slave_t->tx_start, t->rx_buffer, (length+7)/8);
+ }
+ return ESP_OK;
+}
+
+static void timing_init_transactions(spi_dup_t dup, timing_context_t* context)
+{
+ spi_transaction_t* trans = context->master_trans;
+ uint8_t *rx_buf_ptr = context->master_rxbuf;
+ if (dup==HALF_DUPLEX_MISO) {
+ for (int i = 0; i < 8; i++ ) {
+ trans[i] = (spi_transaction_t) {
+ .flags = 0,
+ .rxlength = 8*(i*2+1),
+ .rx_buffer = rx_buf_ptr,
+ };
+ rx_buf_ptr += ((context->master_trans[i].rxlength + 31)/8)&(~3);
+ }
+ } else if (dup==HALF_DUPLEX_MOSI) {
+ for (int i = 0; i < 8; i++ ) {
+ trans[i] = (spi_transaction_t) {
+ .flags = 0,
+ .length = 8*(i*2+1),
+ .tx_buffer = master_send+i,
+ };
+ }
+ } else {
+ for (int i = 0; i < 8; i++ ) {
+ trans[i] = (spi_transaction_t) {
+ .flags = 0,
+ .length = 8*(i*2+1),
+ .tx_buffer = master_send+i,
+ .rx_buffer = rx_buf_ptr,
+ };
+ rx_buf_ptr += ((context->master_trans[i].length + 31)/8)&(~3);
+ }
+ }
+ //prepare slave tx data
+ for (int i = 0; i < 8; i ++) {
+ context->slave_trans[i] = (slave_txdata_t) {
+ .start = slave_send + 4*(i%3),
+ .len = 256,
+ };
+ }
+}
+
+typedef struct {
+ const char cfg_name[30];
+ /*The test work till the frequency below,
+ *set the frequency to higher and remove checks in the driver to know how fast the system can run.
+ */
+ int freq_limit;
+ spi_dup_t dup;
+ bool master_iomux;
+ bool slave_iomux;
+ int slave_tv_ns;
+} test_timing_config_t;
+
+#define ESP_SPI_SLAVE_TV (12.5*3)
+#define GPIO_DELAY (12.5*2)
+#define SAMPLE_DELAY 12.5
+
+#define TV_INT_CONNECT_GPIO (ESP_SPI_SLAVE_TV+GPIO_DELAY)
+#define TV_INT_CONNECT (ESP_SPI_SLAVE_TV)
+#define TV_WITH_ESP_SLAVE_GPIO (ESP_SPI_SLAVE_TV+SAMPLE_DELAY+GPIO_DELAY)
+#define TV_WITH_ESP_SLAVE (ESP_SPI_SLAVE_TV+SAMPLE_DELAY)
+
+//currently ESP32 slave only supports up to 20MHz, but 40MHz on the same board
+#define ESP_SPI_SLAVE_MAX_FREQ SPI_MASTER_FREQ_20M
+#define ESP_SPI_SLAVE_MAX_FREQ_SYNC SPI_MASTER_FREQ_40M
+
+
+static test_timing_config_t timing_master_conf_t[] = {/**/
+ { .cfg_name = "FULL_DUP, MASTER IOMUX",
+ .freq_limit = SPI_MASTER_FREQ_13M,
+ .dup = FULL_DUPLEX,
+ .master_iomux = true,
+ .slave_iomux = false,
+ .slave_tv_ns = TV_INT_CONNECT_GPIO,
+ },
+ { .cfg_name = "FULL_DUP, SLAVE IOMUX",
+ .freq_limit = SPI_MASTER_FREQ_13M,
+ .dup = FULL_DUPLEX,
+ .master_iomux = false,
+ .slave_iomux = true,
+ .slave_tv_ns = TV_INT_CONNECT,
+ },
+ { .cfg_name = "FULL_DUP, BOTH GPIO",
+ .freq_limit = SPI_MASTER_FREQ_10M,
+ .dup = FULL_DUPLEX,
+ .master_iomux = false,
+ .slave_iomux = false,
+ .slave_tv_ns = TV_INT_CONNECT_GPIO,
+ },
+ { .cfg_name = "HALF_DUP, MASTER IOMUX",
+ .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
+ .dup = HALF_DUPLEX_MISO,
+ .master_iomux = true,
+ .slave_iomux = false,
+ .slave_tv_ns = TV_INT_CONNECT_GPIO,
+ },
+ { .cfg_name = "HALF_DUP, SLAVE IOMUX",
+ .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
+ .dup = HALF_DUPLEX_MISO,
+ .master_iomux = false,
+ .slave_iomux = true,
+ .slave_tv_ns = TV_INT_CONNECT,
+ },
+ { .cfg_name = "HALF_DUP, BOTH GPIO",
+ .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
+ .dup = HALF_DUPLEX_MISO,
+ .master_iomux = false,
+ .slave_iomux = false,
+ .slave_tv_ns = TV_INT_CONNECT_GPIO,
+ },
+ { .cfg_name = "MOSI_DUP, MASTER IOMUX",
+ .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
+ .dup = HALF_DUPLEX_MOSI,
+ .master_iomux = true,
+ .slave_iomux = false,
+ .slave_tv_ns = TV_INT_CONNECT_GPIO,
+ },
+ { .cfg_name = "MOSI_DUP, SLAVE IOMUX",
+ .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
+ .dup = HALF_DUPLEX_MOSI,
+ .master_iomux = false,
+ .slave_iomux = true,
+ .slave_tv_ns = TV_INT_CONNECT,
+ },
+ { .cfg_name = "MOSI_DUP, BOTH GPIO",
+ .freq_limit = ESP_SPI_SLAVE_MAX_FREQ_SYNC,
+ .dup = HALF_DUPLEX_MOSI,
+ .master_iomux = false,
+ .slave_iomux = false,
+ .slave_tv_ns = TV_INT_CONNECT_GPIO,
+ },
+};
+
+//this case currently only checks master read
+TEST_CASE("test timing_master","[spi][timeout=120]")
+{
+ timing_context_t context;
+
+ //Enable pull-ups on SPI lines so we don't detect rogue pulses when no master is connected.
+ //slave_pull_up(&slv_buscfg, slvcfg.spics_io_num);
+
+ context.slave_context = (spi_slave_task_context_t){};
+ esp_err_t err = init_slave_context( &context.slave_context );
+ TEST_ASSERT( err == ESP_OK );
+
+ xTaskCreate( task_slave, "spi_slave", 4096, &context.slave_context, 0, &context.handle_slave);
+
+ const int test_size = sizeof(timing_master_conf_t)/sizeof(test_timing_config_t);
+ for (int i = 0; i < test_size; i++) {
+ test_timing_config_t* conf = &timing_master_conf_t[i];
+
+ spi_device_handle_t spi;
+
+ timing_init_transactions(conf->dup, &context);
+
+ ESP_LOGI(MASTER_TAG, "****************** %s ***************", conf->cfg_name);
+ for (int j=0; j conf->freq_limit) break;
+ ESP_LOGI(MASTER_TAG, "======> %dk", timing_speed_array[j]/1000);
+
+ //master config
+ const int master_mode = 0;
+ spi_bus_config_t buscfg=SPI_BUS_TEST_DEFAULT_CONFIG();
+ spi_device_interface_config_t devcfg=SPI_DEVICE_TEST_DEFAULT_CONFIG();
+ devcfg.mode = master_mode;
+ if (conf->dup==HALF_DUPLEX_MISO||conf->dup==HALF_DUPLEX_MOSI) {
+ devcfg.cs_ena_pretrans = 20;
+ devcfg.flags |= SPI_DEVICE_HALFDUPLEX;
+ } else {
+ devcfg.cs_ena_pretrans = 1;
+ }
+ devcfg.cs_ena_posttrans = 20;
+ devcfg.input_delay_ns = conf->slave_tv_ns;
+ devcfg.clock_speed_hz = timing_speed_array[j];
+
+ //slave config
+ int slave_mode = 0;
+ spi_slave_interface_config_t slvcfg=SPI_SLAVE_TEST_DEFAULT_CONFIG();
+ slvcfg.mode = slave_mode;
+
+ //pin config & initialize
+ //we can't have two sets of iomux pins on the same pins
+ assert(!conf->master_iomux || !conf->slave_iomux);
+ if (conf->slave_iomux) {
+ //only in this case, use VSPI iomux pins
+ buscfg.miso_io_num = VSPI_IOMUX_PIN_NUM_MISO;
+ buscfg.mosi_io_num = VSPI_IOMUX_PIN_NUM_MOSI;
+ buscfg.sclk_io_num = VSPI_IOMUX_PIN_NUM_CLK;
+ devcfg.spics_io_num = VSPI_IOMUX_PIN_NUM_CS;
+ slvcfg.spics_io_num = VSPI_IOMUX_PIN_NUM_CS;
+ } else {
+ buscfg.miso_io_num = HSPI_IOMUX_PIN_NUM_MISO;
+ buscfg.mosi_io_num = HSPI_IOMUX_PIN_NUM_MOSI;
+ buscfg.sclk_io_num = HSPI_IOMUX_PIN_NUM_CLK;
+ devcfg.spics_io_num = HSPI_IOMUX_PIN_NUM_CS;
+ slvcfg.spics_io_num = HSPI_IOMUX_PIN_NUM_CS;
+ }
+ slave_pull_up(&buscfg, slvcfg.spics_io_num);
+
+ //this does nothing, but avoid the driver from using iomux pins if required
+ buscfg.quadhd_io_num = (!conf->master_iomux && !conf->slave_iomux? VSPI_IOMUX_PIN_NUM_MISO: -1);
+ TEST_ESP_OK(spi_bus_initialize(HSPI_HOST, &buscfg, 0));
+ TEST_ESP_OK(spi_bus_add_device(HSPI_HOST, &devcfg, &spi));
+ //slave automatically use iomux pins if pins are on VSPI_* pins
+ buscfg.quadhd_io_num = -1;
+ TEST_ESP_OK( spi_slave_initialize(VSPI_HOST, &buscfg, &slvcfg, 0) );
+
+ //initialize master and slave on the same pins break some of the output configs, fix them
+ if (conf->master_iomux) {
+ gpio_output_sel(buscfg.mosi_io_num, FUNC_SPI, HSPID_OUT_IDX);
+ gpio_output_sel(buscfg.miso_io_num, FUNC_GPIO, VSPIQ_OUT_IDX);
+ gpio_output_sel(devcfg.spics_io_num, FUNC_SPI, HSPICS0_OUT_IDX);
+ gpio_output_sel(buscfg.sclk_io_num, FUNC_SPI, HSPICLK_OUT_IDX);
+ } else if (conf->slave_iomux) {
+ gpio_output_sel(buscfg.mosi_io_num, FUNC_GPIO, HSPID_OUT_IDX);
+ gpio_output_sel(buscfg.miso_io_num, FUNC_SPI, VSPIQ_OUT_IDX);
+ gpio_output_sel(devcfg.spics_io_num, FUNC_GPIO, HSPICS0_OUT_IDX);
+ gpio_output_sel(buscfg.sclk_io_num, FUNC_GPIO, HSPICLK_OUT_IDX);
+ } else {
+ gpio_output_sel(buscfg.mosi_io_num, FUNC_GPIO, HSPID_OUT_IDX);
+ gpio_output_sel(buscfg.miso_io_num, FUNC_GPIO, VSPIQ_OUT_IDX);
+ gpio_output_sel(devcfg.spics_io_num, FUNC_GPIO, HSPICS0_OUT_IDX);
+ gpio_output_sel(buscfg.sclk_io_num, FUNC_GPIO, HSPICLK_OUT_IDX);
+ }
+
+ //clear master receive buffer
+ memset(context.master_rxbuf, 0x66, sizeof(context.master_rxbuf));
+
+ //prepare slave tx data
+ for (int k = 0; k < 8; k ++) xQueueSend( context.slave_context.data_to_send, &context.slave_trans[k], portMAX_DELAY );
+
+ for( int k= 0; k < 8; k ++ ) {
+ //wait for both master and slave end
+ ESP_LOGI( MASTER_TAG, "=> test%d", k );
+ //send master tx data
+ vTaskDelay(9);
+
+ spi_transaction_t *t = &context.master_trans[k];
+ TEST_ESP_OK (spi_device_transmit( spi, t) );
+ master_print_data(t, conf->dup);
+
+ size_t rcv_len;
+ slave_rxdata_t *rcv_data = xRingbufferReceive( context.slave_context.data_received, &rcv_len, portMAX_DELAY );
+ slave_print_data(rcv_data);
+
+ //check result
+ TEST_ESP_OK(check_data(t, conf->dup, rcv_data));
+ //clean
+ vRingbufferReturnItem(context.slave_context.data_received, rcv_data);
+ }
+ master_deinit(spi);
+ TEST_ASSERT(spi_slave_free(VSPI_HOST) == ESP_OK);
+ }
+ }
+
+ vTaskDelete( context.handle_slave );
+ context.handle_slave = 0;
+
+ deinit_slave_context(&context.slave_context);
+
+ ESP_LOGI(MASTER_TAG, "test passed.");
+}
+
+/********************************************************************************
+ * Test SPI transaction interval
+ ********************************************************************************/
#define RECORD_TIME_PREPARE() uint32_t __t1, __t2
#define RECORD_TIME_START() do {__t1 = xthal_get_ccount();}while(0)
#define RECORD_TIME_END(p_time) do{__t2 = xthal_get_ccount(); *p_time = (__t2-__t1)/240;}while(0)
@@ -887,21 +1279,10 @@ TEST_CASE("SPI master variable cmd & addr test","[spi]")
static void speed_setup(spi_device_handle_t* spi, bool use_dma)
{
esp_err_t ret;
- spi_bus_config_t buscfg={
- .miso_io_num=PIN_NUM_MISO,
- .mosi_io_num=PIN_NUM_MOSI,
- .sclk_io_num=PIN_NUM_CLK,
- .quadwp_io_num=-1,
- .quadhd_io_num=-1
- };
- spi_device_interface_config_t devcfg={
- .clock_speed_hz=10*1000*1000, //currently only up to 4MHz for internel connect
- .mode=0, //SPI mode 0
- .spics_io_num=PIN_NUM_CS, //CS pin
- .queue_size=8, //We want to be able to queue 7 transactions at a time
- .pre_cb=NULL,
- .cs_ena_pretrans = 0,
- };
+ spi_bus_config_t buscfg=SPI_BUS_TEST_DEFAULT_CONFIG();
+ spi_device_interface_config_t devcfg=SPI_DEVICE_TEST_DEFAULT_CONFIG();
+ devcfg.queue_size=8; //We want to be able to queue 7 transactions at a time
+
//Initialize the SPI bus and the device to test
ret=spi_bus_initialize(HSPI_HOST, &buscfg, (use_dma?1:0));
TEST_ASSERT(ret==ESP_OK);
@@ -930,12 +1311,12 @@ static void sorted_array_insert(uint32_t* array, int* size, uint32_t item)
TEST_CASE("spi_speed","[spi]")
{
- RECORD_TIME_PREPARE();
+ RECORD_TIME_PREPARE();
uint32_t t_flight;
//to get rid of the influence of randomly interrupts, we measured the performance by median value
uint32_t t_flight_sorted[TEST_TIMES];
int t_flight_num = 0;
-
+
spi_device_handle_t spi;
const bool use_dma = true;
WORD_ALIGNED_ATTR spi_transaction_t trans = {
@@ -948,37 +1329,39 @@ TEST_CASE("spi_speed","[spi]")
//first time introduces a device switch, which costs more time. we skip this
spi_device_transmit(spi, &trans);
-
+
//record flight time by isr, with DMA
t_flight_num = 0;
for (int i = 0; i < TEST_TIMES; i++) {
+ spi_device_transmit(spi, &trans); // prime the flash cache
RECORD_TIME_START();
spi_device_transmit(spi, &trans);
- RECORD_TIME_END(&t_flight);
+ RECORD_TIME_END(&t_flight);
sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight);
}
TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_NO_POLLING, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]);
for (int i = 0; i < TEST_TIMES; i++) {
ESP_LOGI(TAG, "%d", t_flight_sorted[i]);
}
-
+
speed_deinit(spi);
speed_setup(&spi, !use_dma);
-
+
//first time introduces a device switch, which costs more time. we skip this
spi_device_transmit(spi, &trans);
-
+
//record flight time by isr, without DMA
t_flight_num = 0;
for (int i = 0; i < TEST_TIMES; i++) {
RECORD_TIME_START();
spi_device_transmit(spi, &trans);
- RECORD_TIME_END(&t_flight);
+ RECORD_TIME_END(&t_flight);
sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight);
}
TEST_PERFORMANCE_LESS_THAN( SPI_PER_TRANS_NO_POLLING_NO_DMA, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]);
for (int i = 0; i < TEST_TIMES; i++) {
ESP_LOGI(TAG, "%d", t_flight_sorted[i]);
- }
- speed_deinit(spi);
+ }
+ speed_deinit(spi);
}
+
diff --git a/components/driver/test/test_timer.c b/components/driver/test/test_timer.c
new file mode 100644
index 0000000000..7f1d3c37fb
--- /dev/null
+++ b/components/driver/test/test_timer.c
@@ -0,0 +1,870 @@
+#include
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "esp_system.h"
+#include "unity.h"
+#include "nvs_flash.h"
+#include "driver/timer.h"
+
+#define TIMER_DIVIDER 16
+#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) /*!< used to calculate counter value */
+#define TIMER_DELTA 0.001
+static bool alarm_flag;
+
+// group0 interruption
+static void test_timer_group0_isr(void *para)
+{
+ int timer_idx = (int) para;
+ uint64_t timer_val;
+ double time;
+ uint64_t alarm_value;
+ alarm_flag = true;
+ if (TIMERG0.hw_timer[timer_idx].config.autoreload == 1) {
+ if (timer_idx == 0) {
+ TIMERG0.int_clr_timers.t0 = 1;
+ } else {
+ TIMERG0.int_clr_timers.t1 = 1;
+ }
+ ets_printf("This is TG0 timer[%d] reload-timer alarm!\n", timer_idx);
+ timer_get_counter_value(TIMER_GROUP_0, timer_idx, &timer_val);
+ timer_get_counter_time_sec(TIMER_GROUP_0, timer_idx, &time);
+ ets_printf("time: %.8f S\n", time);
+ } else {
+ if (timer_idx == 0) {
+ TIMERG0.int_clr_timers.t0 = 1;
+ } else {
+ TIMERG0.int_clr_timers.t1 = 1;
+ }
+ ets_printf("This is TG0 timer[%d] count-up-timer alarm!\n", timer_idx);
+ timer_get_counter_value(TIMER_GROUP_0, timer_idx, &timer_val);
+ timer_get_counter_time_sec(TIMER_GROUP_0, timer_idx, &time);
+ timer_get_alarm_value(TIMER_GROUP_0, timer_idx, &alarm_value);
+ ets_printf("time: %.8f S\n", time);
+ double alarm_time = (double) alarm_value / TIMER_SCALE;
+ ets_printf("alarm_time: %.8f S\n", alarm_time);
+ }
+}
+
+// group1 interruption
+static void test_timer_group1_isr(void *para)
+{
+ int timer_idx = (int) para;
+ uint64_t timer_val;
+ double time;
+ uint64_t alarm_value;
+ alarm_flag = true;
+ if (TIMERG1.hw_timer[timer_idx].config.autoreload == 1) {
+ if (timer_idx == 0) {
+ TIMERG1.int_clr_timers.t0 = 1;
+ } else {
+ TIMERG1.int_clr_timers.t1 = 1;
+ }
+ ets_printf("This is TG1 timer[%d] reload-timer alarm!\n", timer_idx);
+ timer_get_counter_value(TIMER_GROUP_1, timer_idx, &timer_val);
+ timer_get_counter_time_sec(TIMER_GROUP_1, timer_idx, &time);
+ ets_printf("time: %.8f S\n", time);
+ } else {
+ if (timer_idx == 0) {
+ TIMERG1.int_clr_timers.t0 = 1;
+ } else {
+ TIMERG1.int_clr_timers.t1 = 1;
+ }
+ ets_printf("This is TG1 timer[%d] count-up-timer alarm!\n", timer_idx);
+ timer_get_counter_value(TIMER_GROUP_1, timer_idx, &timer_val);
+ timer_get_counter_time_sec(TIMER_GROUP_1, timer_idx, &time);
+ timer_get_alarm_value(TIMER_GROUP_1, timer_idx, &alarm_value);
+ ets_printf("time: %.8f S\n", time);
+ double alarm_time = (double) alarm_value / TIMER_SCALE;
+ ets_printf("alarm_time: %.8f S\n", alarm_time);
+ }
+}
+
+// initialize exact timer group
+static void tg_timer_init(int timer_group, int timer_idx, double alarm_time)
+{
+ timer_pause(timer_group, timer_idx);
+ timer_set_counter_value(timer_group, timer_idx, 0x0);
+ timer_set_alarm_value(timer_group, timer_idx, alarm_time * TIMER_SCALE);
+ timer_enable_intr(timer_group, timer_idx);
+ if (timer_group == 0) {
+ timer_isr_register(timer_group, timer_idx, test_timer_group0_isr,
+ (void *) timer_idx, ESP_INTR_FLAG_LOWMED, NULL);
+ } else {
+ timer_isr_register(timer_group, timer_idx, test_timer_group1_isr,
+ (void *) timer_idx, ESP_INTR_FLAG_LOWMED, NULL);
+ }
+ timer_start(timer_group, timer_idx);
+}
+
+// initialize all timer
+static void all_timer_init(timer_config_t config, bool flag)
+{
+ esp_err_t ret;
+ ret = timer_init(TIMER_GROUP_0, TIMER_0, &config);
+ if (flag) {
+ TEST_ASSERT(ret == ESP_OK);
+ } else {
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ }
+ ret = timer_init(TIMER_GROUP_0, TIMER_1, &config);
+ if (flag) {
+ TEST_ASSERT(ret == ESP_OK);
+ } else {
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ }
+ ret = timer_init(TIMER_GROUP_1, TIMER_0, &config);
+ if (flag) {
+ TEST_ASSERT(ret == ESP_OK);
+ } else {
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ }
+ ret = timer_init(TIMER_GROUP_1, TIMER_1, &config);
+ if (flag) {
+ TEST_ASSERT(ret == ESP_OK);
+ } else {
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ }
+}
+
+// start all of timer
+static void all_timer_start()
+{
+ esp_err_t ret;
+ ret = timer_start(TIMER_GROUP_0, TIMER_0);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_start(TIMER_GROUP_0, TIMER_1);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_start(TIMER_GROUP_1, TIMER_0);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_start(TIMER_GROUP_1, TIMER_1);
+ TEST_ASSERT(ret == ESP_OK);
+}
+
+static void all_timer_set_counter_value(uint64_t set_timer_val)
+{
+ esp_err_t ret;
+ ret = timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_set_counter_value(TIMER_GROUP_0, TIMER_1, set_timer_val);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_set_counter_value(TIMER_GROUP_1, TIMER_0, set_timer_val);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_set_counter_value(TIMER_GROUP_1, TIMER_1, set_timer_val);
+ TEST_ASSERT(ret == ESP_OK);
+}
+
+static void all_timer_pause()
+{
+ esp_err_t ret;
+ ret = timer_pause(TIMER_GROUP_0, TIMER_0);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_pause(TIMER_GROUP_0, TIMER_1);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_pause(TIMER_GROUP_1, TIMER_0);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_pause(TIMER_GROUP_1, TIMER_1);
+ TEST_ASSERT(ret == ESP_OK);
+}
+
+static void all_timer_get_counter_value(uint64_t set_timer_val, bool flag,
+ uint64_t *counter_val)
+{
+ esp_err_t ret;
+ uint64_t time_val;
+ ret = timer_get_counter_value(TIMER_GROUP_0, TIMER_0, &time_val);
+ TEST_ASSERT(ret == ESP_OK);
+ if (flag == true) {
+ TEST_ASSERT(set_timer_val == time_val);
+ } else {
+ TEST_ASSERT(set_timer_val != time_val);
+ if (counter_val != NULL) {
+ counter_val[0] = time_val;
+ }
+ }
+ ret = timer_get_counter_value(TIMER_GROUP_0, TIMER_1, &time_val);
+ TEST_ASSERT(ret == ESP_OK);
+ if (flag) {
+ TEST_ASSERT(set_timer_val == time_val);
+ } else {
+ TEST_ASSERT(set_timer_val != time_val);
+ if (counter_val != NULL) {
+ counter_val[1] = time_val;
+ }
+ }
+ ret = timer_get_counter_value(TIMER_GROUP_1, TIMER_0, &time_val);
+ TEST_ASSERT(ret == ESP_OK);
+ if (flag) {
+ TEST_ASSERT(set_timer_val == time_val);
+ } else {
+ TEST_ASSERT(set_timer_val != time_val);
+ if (counter_val != NULL) {
+ counter_val[2] = time_val;
+ }
+ }
+ ret = timer_get_counter_value(TIMER_GROUP_1, TIMER_1, &time_val);
+ TEST_ASSERT(ret == ESP_OK);
+ if (flag) {
+ TEST_ASSERT(set_timer_val == time_val);
+ } else {
+ TEST_ASSERT(set_timer_val != time_val);
+ if (counter_val != NULL) {
+ counter_val[3] = time_val;
+ }
+ }
+}
+
+static void all_timer_get_counter_time_sec(bool flag, int delay_time)
+{
+ double time;
+ esp_err_t ret;
+ ret = timer_get_counter_time_sec(TIMER_GROUP_0, TIMER_0, &time);
+ TEST_ASSERT(ret == ESP_OK);
+ if (!flag) {
+ TEST_ASSERT_FLOAT_WITHIN(TIMER_DELTA, delay_time, time);
+ }
+ ret = timer_get_counter_time_sec(TIMER_GROUP_0, TIMER_1, &time);
+ TEST_ASSERT(ret == ESP_OK);
+ if (!flag) {
+ TEST_ASSERT_FLOAT_WITHIN(TIMER_DELTA, delay_time, time);
+ }
+ ret = timer_get_counter_time_sec(TIMER_GROUP_1, TIMER_0, &time);
+ TEST_ASSERT(ret == ESP_OK);
+ if (!flag) {
+ TEST_ASSERT_FLOAT_WITHIN(TIMER_DELTA, delay_time, time);
+ }
+ ret = timer_get_counter_time_sec(TIMER_GROUP_1, TIMER_1, &time);
+ TEST_ASSERT(ret == ESP_OK);
+ if (!flag) {
+ TEST_ASSERT_FLOAT_WITHIN(TIMER_DELTA, delay_time, time);
+ }
+}
+
+static void all_timer_set_counter_mode(timer_count_dir_t counter_dir)
+{
+ esp_err_t ret;
+ ret = timer_set_counter_mode(TIMER_GROUP_0, TIMER_0, counter_dir);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_set_counter_mode(TIMER_GROUP_0, TIMER_1, counter_dir);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_set_counter_mode(TIMER_GROUP_1, TIMER_0, counter_dir);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_set_counter_mode(TIMER_GROUP_1, TIMER_1, counter_dir);
+ TEST_ASSERT(ret == ESP_OK);
+}
+
+static void all_timer_set_divider(uint32_t divider)
+{
+ esp_err_t ret;
+ ret = timer_set_divider(TIMER_GROUP_0, TIMER_0, divider);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_set_divider(TIMER_GROUP_0, TIMER_1, divider);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_set_divider(TIMER_GROUP_1, TIMER_0, divider);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_set_divider(TIMER_GROUP_1, TIMER_1, divider);
+ TEST_ASSERT(ret == ESP_OK);
+}
+
+static void all_timer_set_alarm_value(double alarm_time)
+{
+ esp_err_t ret;
+ ret = timer_set_alarm_value(TIMER_GROUP_0, TIMER_0,
+ alarm_time * TIMER_SCALE);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_set_alarm_value(TIMER_GROUP_0, TIMER_1,
+ alarm_time * TIMER_SCALE);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_set_alarm_value(TIMER_GROUP_1, TIMER_0,
+ alarm_time * TIMER_SCALE);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_set_alarm_value(TIMER_GROUP_1, TIMER_1,
+ alarm_time * TIMER_SCALE);
+ TEST_ASSERT(ret == ESP_OK);
+}
+
+TEST_CASE("Timer init", "[hw_timer]")
+{
+ esp_err_t ret;
+
+ // Test init 1:config para
+ // empty para
+ timer_config_t config0 = { };
+ all_timer_init(config0, false);
+
+ // only one para
+ timer_config_t config1 = {
+ .auto_reload = 1
+ };
+ all_timer_init(config1, false);
+
+ // lack one para
+ timer_config_t config2 = {
+ .auto_reload = 1,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = 1,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+ all_timer_init(config2, true);
+
+ config2.counter_en = 0;
+ all_timer_init(config2, true);
+
+
+ // error config para
+ timer_config_t config3 = {
+ .alarm_en = 3, //error para
+ .auto_reload = 1,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = 1,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+ all_timer_init(config3, true);
+ timer_config_t get_config;
+ timer_get_config(TIMER_GROUP_1, TIMER_1, &get_config);
+ printf("Error config alarm_en is %d\n", get_config.alarm_en);
+ TEST_ASSERT(config3.alarm_en != get_config.alarm_en);
+
+ // Test init 2: init
+ uint64_t set_timer_val = 0x0;
+ timer_config_t config = {
+ .alarm_en = 0,
+ .auto_reload = 1,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = 1,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+
+ // judge get config parameters
+ timer_init(TIMER_GROUP_0, TIMER_0, &config);
+ timer_get_config(TIMER_GROUP_0, TIMER_0, &get_config);
+ TEST_ASSERT(config.alarm_en == get_config.alarm_en);
+ TEST_ASSERT(config.auto_reload == get_config.auto_reload);
+ TEST_ASSERT(config.counter_dir == get_config.counter_dir);
+ TEST_ASSERT(config.counter_en == get_config.counter_en);
+ TEST_ASSERT(config.intr_type == get_config.intr_type);
+ TEST_ASSERT(config.divider == get_config.divider);
+
+ all_timer_init(config, true);
+ all_timer_pause();
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_start();
+ all_timer_get_counter_value(set_timer_val, false, NULL);
+
+ // Test init 3: wrong para
+ ret = timer_init(-1, TIMER_1, &config);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ ret = timer_init(TIMER_GROUP_1, 2, &config);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ ret = timer_init(TIMER_GROUP_1, -1, &config);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ ret = timer_init(2, TIMER_1, &config);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+
+}
+
+/**
+ * read count case:
+ * 1. start timer compare value
+ * 2. pause timer compare value
+ * 3. delay some time */
+TEST_CASE("Timer read counter value", "[hw_timer]")
+{
+ timer_config_t config = {
+ .alarm_en = 1,
+ .auto_reload = 1,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = 1,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+ uint64_t set_timer_val = 0x0;
+
+ all_timer_init(config, true);
+
+ // Test read value 1: start timer get counter value
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_start();
+ all_timer_get_counter_value(set_timer_val, false, NULL);
+
+ // Test read value 2: pause timer get counter value
+ all_timer_pause();
+ set_timer_val = 0x30405000ULL;
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_get_counter_value(set_timer_val, true, NULL);
+
+ // Test read value 3:delay 1s get counter value
+ set_timer_val = 0x0;
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_start();
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
+ all_timer_get_counter_time_sec(true, 1);
+}
+
+/**
+ * start timer case:
+ * 1. normal start
+ * 2. error start para
+ * */
+TEST_CASE("Timer start", "[hw_timer]")
+{
+ esp_err_t ret;
+ timer_config_t config = {
+ .alarm_en = 1,
+ .auto_reload = 1,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = 1,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+ uint64_t set_timer_val = 0x0;
+ all_timer_init(config, true);
+
+ //Test start 1: normal start
+ all_timer_start();
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_get_counter_value(set_timer_val, false, NULL);
+
+ //Test start 2:wrong para
+ ret = timer_start(2, TIMER_1);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ ret = timer_start(-1, TIMER_1);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ ret = timer_start(TIMER_GROUP_1, 2);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ ret = timer_start(TIMER_GROUP_1, -1);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+}
+
+/**
+ * pause timer case:
+ * 1. normal pause, read value
+ * 2. error pause error
+ */
+TEST_CASE("Timer pause", "[hw_timer]")
+{
+ esp_err_t ret;
+ timer_config_t config = {
+ .alarm_en = 1,
+ .auto_reload = 1,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = 1,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+ uint64_t set_timer_val = 0x0;
+ all_timer_init(config, true);
+
+ //Test pause 1: right para
+ all_timer_pause();
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_get_counter_value(set_timer_val, true, NULL);
+
+ //Test pause 2: wrong para
+ ret = timer_pause(-1, TIMER_0);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ ret = timer_pause(TIMER_GROUP_0, -1);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ ret = timer_pause(2, TIMER_0);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ ret = timer_pause(TIMER_GROUP_1, 2);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+}
+
+// positive mode and negative mode
+TEST_CASE("Timer counter mode (up / down)", "[hw_timer]")
+{
+ esp_err_t ret;
+ timer_config_t config = {
+ .alarm_en = 1,
+ .auto_reload = 1,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = 1,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+ uint64_t set_timer_val = 0x0;
+ all_timer_init(config, true);
+ all_timer_pause();
+
+ // Test counter mode 1: TIMER_COUNT_UP
+ all_timer_set_counter_mode(TIMER_COUNT_UP);
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_start();
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
+ all_timer_get_counter_time_sec(true, 1);
+
+ // Test counter mode 2: TIMER_COUNT_DOWN
+ all_timer_pause();
+ set_timer_val = 0x00E4E1C0ULL; // 3s clock counter value
+ all_timer_set_counter_mode(TIMER_COUNT_DOWN);
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_start();
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
+ all_timer_get_counter_time_sec(true, 2);
+
+ // Test counter mode 3 : wrong para
+ ret = timer_set_counter_mode(TIMER_GROUP_0, TIMER_0, -1);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+ ret = timer_set_counter_mode(TIMER_GROUP_0, TIMER_0, 2);
+ TEST_ASSERT(ret == ESP_ERR_INVALID_ARG);
+}
+
+/**
+ * divider case:
+ * 1. different divider, read value
+ * Note: divide 0 = divide max, divide 1 = divide 2
+ * 2. error para
+ *
+ * the frequency(timer counts in one sec):
+ * 80M/divider = 800*100000
+ * max divider value is 65536, its frequency is 1220 (nearly about 1KHz)
+ */
+TEST_CASE("Timer divider", "[hw_timer]")
+{
+ int i;
+ timer_config_t config = {
+ .alarm_en = 1,
+ .auto_reload = 1,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = 1,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+ uint64_t set_timer_val = 0;
+ uint64_t time_val[4];
+ uint64_t comp_time_val[4];
+ all_timer_init(config, true);
+
+ all_timer_pause();
+ all_timer_set_counter_value(set_timer_val);
+
+ all_timer_start();
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
+ all_timer_get_counter_value(set_timer_val, false, time_val);
+
+ // compare divider 16 and 8, value should be double
+ all_timer_pause();
+ all_timer_set_divider(8);
+ all_timer_set_counter_value(set_timer_val);
+
+ all_timer_start();
+ vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time
+ all_timer_get_counter_value(set_timer_val, false, comp_time_val);
+ for (i = 0; i < 4; i++) {
+ TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]);
+ TEST_ASSERT_INT_WITHIN(10000, 10000000, comp_time_val[i]);
+ }
+
+ // divider is 256, value should be 2^4
+ all_timer_pause();
+ all_timer_set_divider(256);
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_start();
+ vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time
+ all_timer_get_counter_value(set_timer_val, false, comp_time_val);
+ for (i = 0; i < 4; i++) {
+ TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]);
+ TEST_ASSERT_INT_WITHIN(3126, 312500, comp_time_val[i]);
+ }
+
+ // extrem value test
+ all_timer_pause();
+ all_timer_set_divider(2);
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_start();
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
+ all_timer_get_counter_value(set_timer_val, false, comp_time_val);
+ for (i = 0; i < 4; i++) {
+ TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]);
+ TEST_ASSERT_INT_WITHIN(40000 , 40000000, comp_time_val[i]);
+ }
+
+ all_timer_pause();
+ all_timer_set_divider(65536);
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_start();
+ vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time
+ all_timer_get_counter_value(set_timer_val, false, comp_time_val);
+ for (i = 0; i < 4; i++) {
+ TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]);
+ TEST_ASSERT_INT_WITHIN(2 , 1220, comp_time_val[i]);
+ }
+
+ // divider is 1 should be equal with 2
+ all_timer_pause();
+ TEST_ASSERT(timer_set_divider(TIMER_GROUP_0, TIMER_0, 1) == ESP_ERR_INVALID_ARG) ;
+ TEST_ASSERT(timer_set_divider(TIMER_GROUP_1, TIMER_0, 1) == ESP_ERR_INVALID_ARG) ;
+ TEST_ASSERT(timer_set_divider(TIMER_GROUP_0, TIMER_1, 1) == ESP_ERR_INVALID_ARG) ;
+ TEST_ASSERT(timer_set_divider(TIMER_GROUP_1, TIMER_1, 1) == ESP_ERR_INVALID_ARG) ;
+
+ all_timer_pause();
+ TEST_ASSERT(timer_set_divider(TIMER_GROUP_0, TIMER_0, 65537) == ESP_ERR_INVALID_ARG) ;
+ TEST_ASSERT(timer_set_divider(TIMER_GROUP_1, TIMER_0, 65537) == ESP_ERR_INVALID_ARG) ;
+ TEST_ASSERT(timer_set_divider(TIMER_GROUP_0, TIMER_1, 65537) == ESP_ERR_INVALID_ARG) ;
+ TEST_ASSERT(timer_set_divider(TIMER_GROUP_1, TIMER_1, 65537) == ESP_ERR_INVALID_ARG) ;
+}
+
+/**
+ * enable alarm case:
+ * 1. enable alarm ,set alarm value and get value
+ * 2. disable alarm ,set alarm value and get value
+ */
+TEST_CASE("Timer enable alarm", "[hw_timer]")
+{
+ timer_config_t config_test = {
+ .alarm_en = 1,
+ .auto_reload = 1,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = 1,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+ all_timer_init(config_test, true);
+
+ // enable alarm
+ alarm_flag = false;
+ tg_timer_init(TIMER_GROUP_0, TIMER_1, 1.2);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ TEST_ASSERT(alarm_flag == true);
+
+ // disable alarm
+ alarm_flag = false;
+ timer_set_alarm(TIMER_GROUP_0, TIMER_1, TIMER_ALARM_DIS);
+ tg_timer_init(TIMER_GROUP_0, TIMER_1, 1.2);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ TEST_ASSERT(alarm_flag == false);
+
+ // enable alarm
+ alarm_flag = false;
+ timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN);
+ tg_timer_init(TIMER_GROUP_1, TIMER_0, 1.2);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ TEST_ASSERT(alarm_flag == true);
+
+ // disable alarm
+ alarm_flag = false;
+ timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_DIS);
+ tg_timer_init(TIMER_GROUP_1, TIMER_0, 1.2);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ TEST_ASSERT(alarm_flag == false);
+}
+
+/**
+ * alarm value case:
+ * 1. set alarm value and get value
+ * 2. interrupt test time
+ */
+TEST_CASE("Timer set alarm value", "[hw_timer]")
+{
+ esp_err_t ret;
+ int i;
+ uint64_t alarm_val[4];
+ timer_config_t config = {
+ .alarm_en = 1,
+ .auto_reload = TIMER_AUTORELOAD_DIS,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = 0,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+ all_timer_init(config, true);
+
+ // set and get alarm value
+ all_timer_set_alarm_value(3);
+ ret = timer_get_alarm_value(TIMER_GROUP_0, TIMER_0, &alarm_val[0]);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_get_alarm_value(TIMER_GROUP_0, TIMER_1, &alarm_val[1]);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_get_alarm_value(TIMER_GROUP_1, TIMER_0, &alarm_val[2]);
+ TEST_ASSERT(ret == ESP_OK);
+ ret = timer_get_alarm_value(TIMER_GROUP_1, TIMER_1, &alarm_val[3]);
+ TEST_ASSERT(ret == ESP_OK);
+ for (i = 0; i < 4; i++) {
+ TEST_ASSERT_EQUAL_UINT32(alarm_val[i] , TIMER_SCALE * 3);
+ }
+
+ // set interrupt read alarm value
+ tg_timer_init(TIMER_GROUP_0, TIMER_1, 2.4);
+ tg_timer_init(TIMER_GROUP_1, TIMER_0, 1.4);
+ vTaskDelay(3000 / portTICK_PERIOD_MS);
+}
+
+/**
+ * auto reload case:
+ * 1. no reload
+ * 2. auto reload
+ */
+TEST_CASE("Timer auto reload", "[hw_timer]")
+{
+ timer_config_t config = {
+ .alarm_en = 1,
+ .auto_reload = TIMER_AUTORELOAD_DIS,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = 1,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+ all_timer_init(config, true);
+
+ // test disable auto_reload
+ tg_timer_init(TIMER_GROUP_0, TIMER_0, 1.14);
+ tg_timer_init(TIMER_GROUP_1, TIMER_1, 1.14);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+
+ //test enable auto_reload
+ timer_set_auto_reload(TIMER_GROUP_0, TIMER_1, TIMER_AUTORELOAD_EN);
+ tg_timer_init(TIMER_GROUP_0, TIMER_1, 1.4);
+ timer_set_auto_reload(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN);
+ tg_timer_init(TIMER_GROUP_1, TIMER_0, 1.4);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+}
+
+/**
+ * timer_enable_intr case:
+ * 1. enable timer_intr
+ * 2. disable timer_intr
+ */
+TEST_CASE("Timer enable timer interrupt", "[hw_timer]")
+{
+ alarm_flag = false;
+ timer_config_t config = {
+ .alarm_en = 1,
+ .auto_reload = TIMER_AUTORELOAD_DIS,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = TIMER_PAUSE,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+ uint64_t set_timer_val = 0x0;
+ all_timer_init(config, true);
+ all_timer_pause();
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_set_alarm_value(1.2);
+
+ // enable timer_intr0
+ timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val);
+ timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 1.2 * TIMER_SCALE);
+ timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group0_isr,
+ (void *) TIMER_0, ESP_INTR_FLAG_LOWMED, NULL);
+ timer_start(TIMER_GROUP_0, TIMER_0);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ TEST_ASSERT(alarm_flag == true)
+
+ // disable timer_intr0
+ alarm_flag = false;
+ timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val);
+ timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 1.2 * TIMER_SCALE);
+ timer_disable_intr(TIMER_GROUP_0, TIMER_0);
+ timer_start(TIMER_GROUP_0, TIMER_0);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ TEST_ASSERT(alarm_flag == false)
+
+ // enable timer_intr1
+ timer_set_counter_value(TIMER_GROUP_1, TIMER_1, set_timer_val);
+ timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, 1.2 * TIMER_SCALE);
+ timer_isr_register(TIMER_GROUP_1, TIMER_1, test_timer_group1_isr,
+ (void *) TIMER_1, ESP_INTR_FLAG_LOWMED, NULL);
+ timer_start(TIMER_GROUP_1, TIMER_1);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ TEST_ASSERT(alarm_flag == true)
+
+ // disable timer_intr1
+ alarm_flag = false;
+ timer_set_counter_value(TIMER_GROUP_1, TIMER_1, set_timer_val);
+ timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, 1.2 * TIMER_SCALE);
+ timer_disable_intr(TIMER_GROUP_1, TIMER_1);
+ timer_start(TIMER_GROUP_1, TIMER_1);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ TEST_ASSERT(alarm_flag == false);
+
+ //enable timer_intr1 again
+ timer_init(TIMER_GROUP_1, TIMER_1, &config);
+ timer_set_counter_value(TIMER_GROUP_1, TIMER_1, set_timer_val);
+ timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, 1.2 * TIMER_SCALE);
+ timer_enable_intr(TIMER_GROUP_1, TIMER_1);
+ timer_start(TIMER_GROUP_1, TIMER_1);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ TEST_ASSERT(alarm_flag == true)
+}
+
+/**
+ * enable timer group case:
+ * 1. enable timer group
+ * 2. disable timer group
+ */
+TEST_CASE("Timer enable timer group interrupt", "[hw_timer][ignore]")
+{
+ alarm_flag = false;
+ timer_config_t config = {
+ .alarm_en = 1,
+ .auto_reload = TIMER_AUTORELOAD_DIS,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = 0,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+ uint64_t set_timer_val = 0x0;
+ all_timer_init(config, true);
+ all_timer_pause();
+ all_timer_set_counter_value(set_timer_val);
+ all_timer_set_alarm_value(1.2);
+
+ // enable timer group
+ timer_group_intr_enable(TIMER_GROUP_0, TIMG_T0_INT_ENA_M);
+ timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group0_isr,
+ (void *) TIMER_0, ESP_INTR_FLAG_LOWMED, NULL);
+ timer_start(TIMER_GROUP_0, TIMER_0);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ TEST_ASSERT(alarm_flag == true);
+
+ //test enable auto_reload
+ alarm_flag = false;
+ timer_group_intr_disable(TIMER_GROUP_0, TIMG_T0_INT_ENA_M);
+ timer_start(TIMER_GROUP_0, TIMER_0);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ TEST_ASSERT(alarm_flag == false);
+
+ timer_group_intr_enable(TIMER_GROUP_0, TIMG_T0_INT_ENA_M);
+ timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group0_isr,
+ (void *) TIMER_0, ESP_INTR_FLAG_LOWMED, NULL);
+ timer_start(TIMER_GROUP_0, TIMER_0);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ TEST_ASSERT(alarm_flag == true);
+}
+
+/**
+ * isr_register case:
+ * Cycle register 15 times, compare the heap size to ensure no memory leaks
+ */
+TEST_CASE("Timer interrupt register", "[hw_timer]")
+{
+ int i;
+ int heap_size = 0;
+ timer_config_t config = {
+ .alarm_en = 1,
+ .auto_reload = TIMER_AUTORELOAD_DIS,
+ .counter_dir = TIMER_COUNT_UP,
+ .divider = TIMER_DIVIDER,
+ .counter_en = TIMER_PAUSE,
+ .intr_type = TIMER_INTR_LEVEL
+ };
+
+ for (i = 0; i < 15; i++) {
+ all_timer_init(config, true);
+ tg_timer_init(TIMER_GROUP_0, TIMER_0, 0.54);
+ tg_timer_init(TIMER_GROUP_1, TIMER_1, 0.34);
+
+ timer_set_auto_reload(TIMER_GROUP_0, TIMER_1, TIMER_AUTORELOAD_EN);
+ tg_timer_init(TIMER_GROUP_0, TIMER_1, 0.4);
+ timer_set_auto_reload(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN);
+ tg_timer_init(TIMER_GROUP_1, TIMER_0, 0.6);
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
+ if (heap_size == 0) {
+ heap_size = esp_get_free_heap_size();
+ }
+ }
+ TEST_ASSERT_INT_WITHIN(100, heap_size, esp_get_free_heap_size());
+}
diff --git a/components/driver/test/test_uart.c b/components/driver/test/test_uart.c
index f49c73ef7c..b6154b2cc8 100644
--- a/components/driver/test/test_uart.c
+++ b/components/driver/test/test_uart.c
@@ -1,7 +1,10 @@
#include
+#include
#include "unity.h"
-#include "driver/uart.h"
+#include "test_utils.h" // unity_send_signal
+#include "driver/uart.h" // for the uart driver access
#include "esp_log.h"
+#include "esp_system.h" // for uint32_t esp_random()
#define UART_TAG "Uart"
#define UART_NUM1 (UART_NUM_1)
@@ -14,6 +17,92 @@
#define UART_TOLERANCE_CHECK(val, uper_limit, lower_limit) ( (val) <= (uper_limit) && (val) >= (lower_limit) )
+// RTS for RS485 Half-Duplex Mode manages DE/~RE
+#define UART1_RTS_PIN (18)
+
+// Number of packets to be send during test
+#define PACKETS_NUMBER (10)
+
+// Wait timeout for uart driver
+#define PACKET_READ_TICS (1000 / portTICK_RATE_MS)
+
+// The table for fast CRC16 calculation
+static const uint8_t crc_hi[] = {
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81,
+ 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
+ 0x40, 0x01, 0xC0,
+ 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1,
+ 0x81, 0x40, 0x01,
+ 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
+ 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+ 0x00, 0xC1, 0x81,
+ 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80,
+ 0x41, 0x01, 0xC0,
+ 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
+ 0x80, 0x41, 0x01,
+ 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00,
+ 0xC1, 0x81, 0x40,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81,
+ 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
+ 0x40, 0x01, 0xC0,
+ 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1,
+ 0x81, 0x40, 0x01,
+ 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01,
+ 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81,
+ 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
+ 0x40, 0x01, 0xC0,
+ 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
+ 0x80, 0x41, 0x01,
+ 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
+ 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81,
+ 0x40
+};
+
+static const uint8_t crc_low[] = {
+ 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
+ 0x05, 0xC5, 0xC4,
+ 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB,
+ 0x0B, 0xC9, 0x09,
+ 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE,
+ 0xDF, 0x1F, 0xDD,
+ 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2,
+ 0x12, 0x13, 0xD3,
+ 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
+ 0x36, 0xF6, 0xF7,
+ 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E,
+ 0xFE, 0xFA, 0x3A,
+ 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B,
+ 0x2A, 0xEA, 0xEE,
+ 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27,
+ 0xE7, 0xE6, 0x26,
+ 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
+ 0x63, 0xA3, 0xA2,
+ 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD,
+ 0x6D, 0xAF, 0x6F,
+ 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8,
+ 0xB9, 0x79, 0xBB,
+ 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4,
+ 0x74, 0x75, 0xB5,
+ 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
+ 0x50, 0x90, 0x91,
+ 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94,
+ 0x54, 0x9C, 0x5C,
+ 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59,
+ 0x58, 0x98, 0x88,
+ 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D,
+ 0x4D, 0x4C, 0x8C,
+ 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
+ 0x41, 0x81, 0x80,
+ 0x40
+};
+
static void uart_config(uint32_t baud_rate, bool use_ref_tick)
{
uart_config_t uart_config = {
@@ -45,4 +134,195 @@ TEST_CASE("test uart get baud-rate","[uart]")
TEST_ASSERT(UART_TOLERANCE_CHECK(baud_rate1, (1.0 + TOLERANCE)*UART_BAUD_11520, (1.0 - TOLERANCE)*UART_BAUD_11520))
TEST_ASSERT(UART_TOLERANCE_CHECK(baud_rate2, (1.0 + TOLERANCE)*UART_BAUD_115200, (1.0 - TOLERANCE)*UART_BAUD_115200))
ESP_LOGI(UART_TAG, "get baud-rate test passed ....\n");
-}
\ No newline at end of file
+}
+
+TEST_CASE("test uart tx data with break","[uart]")
+{
+ const int buf_len = 200;
+ const int send_len = 128;
+ const int brk_len = 10;
+ char *psend = (char *)malloc(buf_len);
+ TEST_ASSERT( psend != NULL);
+ memset(psend, '0', buf_len);
+ uart_config(UART_BAUD_115200, false);
+ printf("Uart%d send %d bytes with break\n", UART_NUM1, send_len);
+ uart_write_bytes_with_break(UART_NUM1, (const char *)psend, send_len, brk_len);
+ uart_wait_tx_done(UART_NUM1, (portTickType)portMAX_DELAY);
+ //If the code is running here, it means the test passed, otherwise it will crash due to the interrupt wdt timeout.
+ printf("Send data with break test passed\n");
+ free(psend);
+}
+
+// Calculate buffer checksum using tables
+// The checksum CRC16 algorithm is specific
+// for Modbus standard and uses polynomial value = 0xA001
+static uint16_t get_buffer_crc16( uint8_t * frame_ptr, uint16_t length )
+{
+ TEST_ASSERT( frame_ptr != NULL);
+
+ uint8_t crc_hi_byte = 0xFF;
+ uint8_t crc_low_byte = 0xFF;
+ int index;
+
+ while ( length-- )
+ {
+ index = crc_low_byte ^ *(frame_ptr++);
+ crc_low_byte = crc_hi_byte ^ crc_hi[index];
+ crc_hi_byte = crc_low[index];
+ }
+ return ((crc_hi_byte << 8) | crc_low_byte);
+}
+
+// Fill the buffer with random numbers and apply CRC16 at the end
+static uint16_t buffer_fill_random(uint8_t *buffer, size_t length)
+{
+ TEST_ASSERT( buffer != NULL);
+ // Packet is too short
+ if (length < 4) {
+ return 0;
+ }
+ for (int i = 0; i < length; i += 4) {
+ uint32_t random = esp_random();
+ memcpy(buffer + i, &random, MIN(length - i, 4));
+ }
+ // Get checksum of the buffer
+ uint16_t crc = get_buffer_crc16((uint8_t*)buffer, (length - 2));
+ // Apply checksum bytes into packet
+ buffer[length - 2] = (uint8_t)(crc & 0xFF); // Set Low byte CRC
+ buffer[length - 1] = (uint8_t)(crc >> 8); // Set High byte CRC
+ return crc;
+}
+
+static void rs485_init()
+{
+ uart_config_t uart_config = {
+ .baud_rate = UART_BAUD_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 = 122,
+ };
+ printf("RS485 port initialization...\r\n");
+ // Configure UART1 parameters
+ uart_param_config(UART_NUM1, &uart_config);
+ // Set UART1 pins(TX: IO4, RX: I05, RTS: IO18, CTS: IO19)
+ uart_set_pin(UART_NUM1, UART1_TX_PIN, UART1_RX_PIN, UART1_RTS_PIN, UART_PIN_NO_CHANGE);
+ // Install UART driver (we don't need an event queue here)
+ uart_driver_install(UART_NUM1, BUF_SIZE * 2, 0, 0, NULL, 0);
+ // Setup rs485 half duplex mode
+ //uart_set_rs485_hd_mode(uart_num, true);
+ uart_set_mode(UART_NUM1, UART_MODE_RS485_HALF_DUPLEX);
+}
+
+static esp_err_t print_packet_data(const char *str, uint8_t *buffer, uint16_t buffer_size)
+{
+ TEST_ASSERT( buffer != NULL);
+ TEST_ASSERT( str != NULL);
+
+ // Calculate the checksum of the buffer
+ uint16_t crc16_calc = get_buffer_crc16(buffer, (buffer_size - 2));
+ uint16_t crc16_in = ((uint16_t)(buffer[buffer_size - 1]) << 8) | buffer[buffer_size - 2];
+ const char* state_str = (crc16_in != crc16_calc) ? "incorrect " : "correct ";
+ // Print an array of data
+ printf("%s%s RS485 packet = [ ", str, state_str);
+ for (int i = 0; i < buffer_size; i++) {
+ printf("0x%.2X ", (uint8_t)buffer[i]);
+ }
+ printf(" ]\r\n");
+ printf("crc_in = 0x%.4X\r\n", (uint16_t)crc16_in);
+ printf("crc_calc = 0x%.4X\r\n", (uint16_t)crc16_calc);
+ esp_err_t result = (crc16_in != crc16_calc) ? ESP_ERR_INVALID_CRC : ESP_OK;
+ return result;
+}
+
+// Slave test case for multi device
+static void rs485_slave()
+{
+ rs485_init();
+ uint8_t* slave_data = (uint8_t*) malloc(BUF_SIZE);
+ uint16_t err_count = 0, good_count = 0;
+ printf("Start recieve loop.\r\n");
+ unity_send_signal("Slave_ready");
+ unity_wait_for_signal("Master_started");
+ for(int pack_count = 0; pack_count < PACKETS_NUMBER; pack_count++) {
+ //Read slave_data from UART
+ int len = uart_read_bytes(UART_NUM1, slave_data, BUF_SIZE, (PACKET_READ_TICS * 2));
+ //Write slave_data back to UART
+ if (len > 2) {
+ esp_err_t status = print_packet_data("Received ", slave_data, len);
+
+ // If received packet is correct then send it back
+ if (status == ESP_OK) {
+ uart_write_bytes(UART_NUM1, (char*)slave_data, len);
+ good_count++;
+ } else {
+ printf("Incorrect packet received.\r\n");
+ err_count++;
+ }
+ } else {
+ printf("Incorrect data packet[%d] received.\r\n", pack_count);
+ err_count++;
+ }
+ }
+ printf("Test completed. Received packets = %d, errors = %d\r\n", good_count, err_count);
+ // Wait for packet to be sent
+ uart_wait_tx_done(UART_NUM1, PACKET_READ_TICS);
+ free(slave_data);
+ uart_driver_delete(UART_NUM1);
+ TEST_ASSERT(err_count < 2);
+}
+
+// Master test of multi device test case.
+// It forms packet with random data, apply generated CRC16 and sends to slave.
+// If response recieved correctly from slave means RS485 channel works.
+static void rs485_master()
+{
+ uint16_t err_count = 0, good_count = 0;
+ rs485_init();
+ uint8_t* master_buffer = (uint8_t*) malloc(BUF_SIZE);
+ uint8_t* slave_buffer = (uint8_t*) malloc(BUF_SIZE);
+ // The master test case should be synchronized with slave
+ unity_wait_for_signal("Slave_ready");
+ unity_send_signal("Master_started");
+ printf("Start recieve loop.\r\n");
+ for(int i = 0; i < PACKETS_NUMBER; i++) {
+ // Form random buffer with CRC16
+ buffer_fill_random(master_buffer, BUF_SIZE);
+ // Print created packet for debugging
+ esp_err_t status = print_packet_data("Send ", master_buffer, BUF_SIZE);
+ TEST_ASSERT(status == ESP_OK);
+ uart_write_bytes(UART_NUM1, (char*)master_buffer, BUF_SIZE);
+ // Read translated packet from slave
+ int len = uart_read_bytes(UART_NUM1, slave_buffer, BUF_SIZE, (PACKET_READ_TICS * 2));
+ // Check if the received packet is too short
+ if (len > 2) {
+ // Print received packet and check checksum
+ esp_err_t status = print_packet_data("Received ", slave_buffer, len);
+ if (status == ESP_OK) {
+ good_count++;
+ printf("Received: %d\r\n", good_count);
+ } else {
+ err_count++;
+ printf("Errors: %d\r\n", err_count);
+ }
+ }
+ else {
+ printf("Incorrect answer from slave.\r\n");
+ err_count++;
+ }
+ }
+ // Free the buffer and delete driver at the end
+ free(master_buffer);
+ uart_driver_delete(UART_NUM1);
+ TEST_ASSERT(err_count <= 1);
+ printf("Test completed. Received packets = %d, errors = %d\r\n", (uint16_t)good_count, (uint16_t)err_count);
+}
+
+/*
+ * This multi devices test case verifies RS485 mode of the uart driver and checks
+ * correctness of RS485 interface channel communication. It requires
+ * RS485 bus driver hardware to be connected to boards.
+*/
+TEST_CASE_MULTIPLE_DEVICES("RS485 half duplex uart multiple devices test.", "[driver][ignore]", rs485_master, rs485_slave);
+
diff --git a/components/driver/uart.c b/components/driver/uart.c
index 94f3c4c655..876f4d0279 100644
--- a/components/driver/uart.c
+++ b/components/driver/uart.c
@@ -44,6 +44,8 @@ static const char* UART_TAG = "uart";
#define UART_EMPTY_THRESH_DEFAULT (10)
#define UART_FULL_THRESH_DEFAULT (120)
#define UART_TOUT_THRESH_DEFAULT (10)
+#define UART_CLKDIV_FRAG_BIT_WIDTH (3)
+#define UART_TOUT_REF_FACTOR_DEFAULT (UART_CLK_FREQ/(REF_CLK_FREQ<uart_mode == mode))
+
typedef struct {
uart_event_type_t type; /*!< UART TX data type */
struct {
@@ -73,6 +78,9 @@ typedef struct {
int queue_size; /*!< UART event queue size*/
QueueHandle_t xQueueUart; /*!< UART queue handler*/
intr_handle_t intr_handle; /*!< UART interrupt handle*/
+ uart_mode_t uart_mode; /*!< UART controller actual mode set by uart_set_mode() */
+ bool coll_det_flg; /*!< UART collision detection flag */
+
//rx parameters
int rx_buffered_len; /*!< UART cached data length */
SemaphoreHandle_t rx_mux; /*!< UART RX data mutex*/
@@ -664,7 +672,13 @@ esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
UART[uart_num]->int_clr.val = UART_INTR_MASK;
if(intr_conf->intr_enable_mask & UART_RXFIFO_TOUT_INT_ENA_M) {
- UART[uart_num]->conf1.rx_tout_thrhd = ((intr_conf->rx_timeout_thresh) & UART_RX_TOUT_THRHD_V);
+ //Hardware issue workaround: when using ref_tick, the rx timeout threshold needs increase to 10 times.
+ //T_ref = T_apb * APB_CLK/(REF_TICK << CLKDIV_FRAG_BIT_WIDTH)
+ if(UART[uart_num]->conf0.tick_ref_always_on == 0) {
+ UART[uart_num]->conf1.rx_tout_thrhd = ((intr_conf->rx_timeout_thresh * UART_TOUT_REF_FACTOR_DEFAULT) & UART_RX_TOUT_THRHD_V);
+ } else {
+ UART[uart_num]->conf1.rx_tout_thrhd = ((intr_conf->rx_timeout_thresh) & UART_RX_TOUT_THRHD_V);
+ }
UART[uart_num]->conf1.rx_tout_en = 1;
} else {
UART[uart_num]->conf1.rx_tout_en = 0;
@@ -724,7 +738,7 @@ static void uart_rx_intr_handler_default(void *param)
p_uart->tx_waiting_fifo = false;
xSemaphoreGiveFromISR(p_uart->tx_fifo_sem, &HPTaskAwoken);
if(HPTaskAwoken == pdTRUE) {
- portYIELD_FROM_ISR() ;
+ portYIELD_FROM_ISR();
}
} else {
//We don't use TX ring buffer, because the size is zero.
@@ -747,14 +761,13 @@ static void uart_rx_intr_handler_default(void *param)
p_uart->tx_ptr = NULL;
p_uart->tx_len_tot = p_uart->tx_head->tx_data.size;
if(p_uart->tx_head->type == UART_DATA_BREAK) {
- p_uart->tx_len_tot = p_uart->tx_head->tx_data.size;
p_uart->tx_brk_flg = 1;
p_uart->tx_brk_len = p_uart->tx_head->tx_data.brk_len;
}
//We have saved the data description from the 1st item, return buffer.
vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &HPTaskAwoken);
if(HPTaskAwoken == pdTRUE) {
- portYIELD_FROM_ISR() ;
+ portYIELD_FROM_ISR();
}
}else if(p_uart->tx_ptr == NULL) {
//Update the TX item pointer, we will need this to return item to buffer.
@@ -771,8 +784,16 @@ static void uart_rx_intr_handler_default(void *param)
if (p_uart->tx_len_tot > 0 && p_uart->tx_ptr && p_uart->tx_len_cur > 0) {
//To fill the TX FIFO.
int send_len = p_uart->tx_len_cur > tx_fifo_rem ? tx_fifo_rem : p_uart->tx_len_cur;
- for(buf_idx = 0; buf_idx < send_len; buf_idx++) {
- WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), *(p_uart->tx_ptr++) & 0xff);
+ // Set RS485 RTS pin before transmission if the half duplex mode is enabled
+ if (UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)) {
+ UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
+ uart_reg->conf0.sw_rts = 0;
+ uart_reg->int_ena.tx_done = 1;
+ UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
+ }
+ for (buf_idx = 0; buf_idx < send_len; buf_idx++) {
+ WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num),
+ *(p_uart->tx_ptr++) & 0xff);
}
p_uart->tx_len_tot -= send_len;
p_uart->tx_len_cur -= send_len;
@@ -781,13 +802,13 @@ static void uart_rx_intr_handler_default(void *param)
//Return item to ring buffer.
vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &HPTaskAwoken);
if(HPTaskAwoken == pdTRUE) {
- portYIELD_FROM_ISR() ;
+ portYIELD_FROM_ISR();
}
p_uart->tx_head = NULL;
p_uart->tx_ptr = NULL;
//Sending item done, now we need to send break if there is a record.
//Set TX break signal after FIFO is empty
- if(p_uart->tx_brk_flg == 1 && p_uart->tx_len_tot == 0) {
+ if(p_uart->tx_len_tot == 0 && p_uart->tx_brk_flg == 1) {
UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
uart_reg->int_ena.tx_brk_done = 0;
uart_reg->idle_conf.tx_brk_num = p_uart->tx_brk_len;
@@ -796,6 +817,8 @@ static void uart_rx_intr_handler_default(void *param)
uart_reg->int_ena.tx_brk_done = 1;
UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
p_uart->tx_waiting_brk = 1;
+ //do not enable TX empty interrupt
+ en_tx_flg = false;
} else {
//enable TX empty interrupt
en_tx_flg = true;
@@ -885,7 +908,7 @@ static void uart_rx_intr_handler_default(void *param)
UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
}
if(HPTaskAwoken == pdTRUE) {
- portYIELD_FROM_ISR() ;
+ portYIELD_FROM_ISR();
}
} else {
uart_disable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA_M | UART_RXFIFO_TOUT_INT_ENA_M);
@@ -943,7 +966,7 @@ static void uart_rx_intr_handler_default(void *param)
} else {
xSemaphoreGiveFromISR(p_uart->tx_brk_sem, &HPTaskAwoken);
if(HPTaskAwoken == pdTRUE) {
- portYIELD_FROM_ISR() ;
+ portYIELD_FROM_ISR();
}
}
} else if(uart_intr_status & UART_TX_BRK_IDLE_DONE_INT_ST_M) {
@@ -952,12 +975,31 @@ static void uart_rx_intr_handler_default(void *param)
} else if(uart_intr_status & UART_AT_CMD_CHAR_DET_INT_ST_M) {
uart_reg->int_clr.at_cmd_char_det = 1;
uart_event.type = UART_PATTERN_DET;
+ } else if ((uart_intr_status & UART_RS485_CLASH_INT_ST_M)
+ || (uart_intr_status & UART_RS485_FRM_ERR_INT_ENA)
+ || (uart_intr_status & UART_RS485_PARITY_ERR_INT_ENA)) {
+ // RS485 collision or frame error interrupt triggered
+ uart_clear_intr_status(uart_num, UART_RS485_CLASH_INT_CLR_M);
+ UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
+ uart_reset_rx_fifo(uart_num);
+ // Set collision detection flag
+ p_uart_obj[uart_num]->coll_det_flg = true;
+ UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
+ uart_event.type = UART_EVENT_MAX;
} else if(uart_intr_status & UART_TX_DONE_INT_ST_M) {
uart_disable_intr_mask(uart_num, UART_TX_DONE_INT_ENA_M);
uart_clear_intr_status(uart_num, UART_TX_DONE_INT_CLR_M);
+ // If RS485 half duplex mode is enable then reset FIFO and
+ // reset RTS pin to start receiver driver
+ if (UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)) {
+ UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
+ uart_reset_rx_fifo(uart_num); // Allows to avoid hardware issue with the RXFIFO reset
+ uart_reg->conf0.sw_rts = 1;
+ UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
+ }
xSemaphoreGiveFromISR(p_uart_obj[uart_num]->tx_done_sem, &HPTaskAwoken);
- if(HPTaskAwoken == pdTRUE) {
- portYIELD_FROM_ISR() ;
+ if (HPTaskAwoken == pdTRUE) {
+ portYIELD_FROM_ISR();
}
} else {
uart_reg->int_clr.val = uart_intr_status; /*simply clear all other intr status*/
@@ -969,7 +1011,7 @@ static void uart_rx_intr_handler_default(void *param)
ESP_EARLY_LOGV(UART_TAG, "UART event queue full");
}
if(HPTaskAwoken == pdTRUE) {
- portYIELD_FROM_ISR() ;
+ portYIELD_FROM_ISR();
}
}
uart_intr_status = uart_reg->int_st.val;
@@ -1026,7 +1068,12 @@ static int uart_fill_fifo(uart_port_t uart_num, const char* buffer, uint32_t len
uint8_t tx_fifo_cnt = UART[uart_num]->status.txfifo_cnt;
uint8_t tx_remain_fifo_cnt = (UART_FIFO_LEN - tx_fifo_cnt);
uint8_t copy_cnt = (len >= tx_remain_fifo_cnt ? tx_remain_fifo_cnt : len);
- for(i = 0; i < copy_cnt; i++) {
+ // Set the RTS pin if RS485 mode is enabled
+ if (UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)) {
+ UART[uart_num]->conf0.sw_rts = 0;
+ UART[uart_num]->int_ena.tx_done = 1;
+ }
+ for (i = 0; i < copy_cnt; i++) {
WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), buffer[i]);
}
return copy_cnt;
@@ -1055,6 +1102,7 @@ static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool
//lock for uart_tx
xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY);
+ p_uart_obj[uart_num]->coll_det_flg = false;
if(p_uart_obj[uart_num]->tx_buf_size > 0) {
int max_size = xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf);
int offset = 0;
@@ -1257,6 +1305,8 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
return ESP_FAIL;
}
p_uart_obj[uart_num]->uart_num = uart_num;
+ p_uart_obj[uart_num]->uart_mode = UART_MODE_UART;
+ p_uart_obj[uart_num]->coll_det_flg = false;
p_uart_obj[uart_num]->tx_fifo_sem = xSemaphoreCreateBinary();
xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem);
p_uart_obj[uart_num]->tx_done_sem = xSemaphoreCreateBinary();
@@ -1393,3 +1443,90 @@ portMUX_TYPE *uart_get_selectlock()
{
return &uart_selectlock;
}
+// Set UART mode
+esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode)
+{
+ UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_ERR_INVALID_STATE);
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ if ((mode == UART_MODE_RS485_COLLISION_DETECT) || (mode == UART_MODE_RS485_APP_CTRL)
+ || (mode == UART_MODE_RS485_HALF_DUPLEX)) {
+ UART_CHECK((UART[uart_num]->conf1.rx_flow_en != 1),
+ "disable hw flowctrl before using RS485 mode", ESP_ERR_INVALID_ARG);
+ }
+ UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
+ UART[uart_num]->rs485_conf.en = 0;
+ UART[uart_num]->rs485_conf.tx_rx_en = 0;
+ UART[uart_num]->rs485_conf.rx_busy_tx_en = 0;
+ UART[uart_num]->conf0.irda_en = 0;
+ UART[uart_num]->conf0.sw_rts = 0;
+ switch (mode) {
+ case UART_MODE_UART:
+ break;
+ case UART_MODE_RS485_COLLISION_DETECT:
+ // This mode allows read while transmitting that allows collision detection
+ p_uart_obj[uart_num]->coll_det_flg = false;
+ // Transmitters output signal loop back to the receivers input signal
+ UART[uart_num]->rs485_conf.tx_rx_en = 0 ;
+ // Transmitter should send data when its receiver is busy
+ UART[uart_num]->rs485_conf.rx_busy_tx_en = 1;
+ UART[uart_num]->rs485_conf.en = 1;
+ // Enable collision detection interrupts
+ uart_enable_intr_mask(uart_num, UART_RXFIFO_TOUT_INT_ENA
+ | UART_RXFIFO_FULL_INT_ENA
+ | UART_RS485_CLASH_INT_ENA
+ | UART_RS485_FRM_ERR_INT_ENA
+ | UART_RS485_PARITY_ERR_INT_ENA);
+ break;
+ case UART_MODE_RS485_APP_CTRL:
+ // Application software control, remove echo
+ UART[uart_num]->rs485_conf.rx_busy_tx_en = 1;
+ UART[uart_num]->rs485_conf.en = 1;
+ break;
+ case UART_MODE_RS485_HALF_DUPLEX:
+ // Enable receiver, sw_rts = 1 generates low level on RTS pin
+ UART[uart_num]->conf0.sw_rts = 1;
+ UART[uart_num]->rs485_conf.en = 1;
+ // Must be set to 0 to automatically remove echo
+ UART[uart_num]->rs485_conf.tx_rx_en = 0;
+ // This is to void collision
+ UART[uart_num]->rs485_conf.rx_busy_tx_en = 1;
+ break;
+ case UART_MODE_IRDA:
+ UART[uart_num]->conf0.irda_en = 1;
+ break;
+ default:
+ UART_CHECK(1, "unsupported uart mode", ESP_ERR_INVALID_ARG);
+ break;
+ }
+ p_uart_obj[uart_num]->uart_mode = mode;
+ UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
+ return ESP_OK;
+}
+
+esp_err_t uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((tout_thresh < 127), "tout_thresh max value is 126", ESP_ERR_INVALID_ARG);
+ UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
+ // The tout_thresh = 1, defines TOUT interrupt timeout equal to
+ // transmission time of one symbol (~11 bit) on current baudrate
+ if (tout_thresh > 0) {
+ UART[uart_num]->conf1.rx_tout_thrhd = (tout_thresh & UART_RX_TOUT_THRHD_V);
+ UART[uart_num]->conf1.rx_tout_en = 1;
+ } else {
+ UART[uart_num]->conf1.rx_tout_en = 0;
+ }
+ UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
+ return ESP_OK;
+}
+
+esp_err_t uart_get_collision_flag(uart_port_t uart_num, bool* collision_flag)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((collision_flag != NULL), "wrong parameter pointer", ESP_ERR_INVALID_ARG);
+ UART_CHECK((UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)
+ || UART_IS_MODE_SET(uart_num, UART_MODE_RS485_COLLISION_DETECT)),
+ "wrong mode", ESP_ERR_INVALID_ARG);
+ *collision_flag = p_uart_obj[uart_num]->coll_det_flg;
+ return ESP_OK;
+}
diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt
index 5fe1819b2f..b26f5efe27 100644
--- a/components/esp32/CMakeLists.txt
+++ b/components/esp32/CMakeLists.txt
@@ -38,7 +38,9 @@ else()
target_linker_script(esp32
"ld/esp32.common.ld"
"ld/esp32.rom.ld"
- "ld/esp32.peripherals.ld")
+ "ld/esp32.peripherals.ld"
+ "ld/esp32.rom.libgcc.ld"
+ )
if(CONFIG_SPIRAM_CACHE_WORKAROUND)
add_compile_options(-mfix-esp32-psram-cache-issue)
diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig
index 1b4e3784b0..dc897dff2f 100644
--- a/components/esp32/Kconfig
+++ b/components/esp32/Kconfig
@@ -143,7 +143,7 @@ config SPIRAM_MALLOC_RESERVE_INTERNAL
int "Reserve this amount of bytes for data that specifically needs to be in DMA or internal memory"
depends on SPIRAM_USE_MALLOC
default 32768
- range 0 131072
+ range 0 262144
help
Because the external/internal RAM allocation strategy is not always perfect, it sometimes may happen
that the internal memory is entirely filled up. This causes allocations that are specifically done in
@@ -156,6 +156,10 @@ config SPIRAM_MALLOC_RESERVE_INTERNAL
Note that because FreeRTOS stacks are forced to internal memory, they will also use this memory pool;
be sure to keep this in mind when adjusting this value.
+ Note also that the DMA reserved pool may not be one single contiguous memory region, depending on the
+ configured size and the static memory usage of the app.
+
+
config SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
bool "Allow external memory as an argument to xTaskCreateStatic"
default n
@@ -694,7 +698,8 @@ config ESP32_RTC_CLK_CAL_CYCLES
int "Number of cycles for RTC_SLOW_CLK calibration"
default 3000 if ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
default 1024 if ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC
- range 0 125000
+ range 0 27000 if ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
+ range 0 32766 if ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC
help
When the startup code initializes RTC_SLOW_CLK, it can perform
calibration by comparing the RTC_SLOW_CLK frequency with main XTAL
diff --git a/components/esp32/Makefile.projbuild b/components/esp32/Makefile.projbuild
index 63318dd66b..9a51d80b3e 100644
--- a/components/esp32/Makefile.projbuild
+++ b/components/esp32/Makefile.projbuild
@@ -4,8 +4,8 @@ PHY_INIT_DATA_OBJ = $(BUILD_DIR_BASE)/phy_init_data.o
PHY_INIT_DATA_BIN = $(BUILD_DIR_BASE)/phy_init_data.bin
# Command to flash PHY init data partition
-PHY_INIT_DATA_FLASH_CMD = $(ESPTOOLPY_SERIAL) write_flash $(CONFIG_PHY_DATA_OFFSET) $(PHY_INIT_DATA_BIN)
-ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_PHY_DATA_OFFSET) $(PHY_INIT_DATA_BIN)
+PHY_INIT_DATA_FLASH_CMD = $(ESPTOOLPY_SERIAL) write_flash $(PHY_DATA_OFFSET) $(PHY_INIT_DATA_BIN)
+ESPTOOL_ALL_FLASH_ARGS += $(PHY_DATA_OFFSET) $(PHY_INIT_DATA_BIN)
ESP32_COMPONENT_PATH := $(COMPONENT_PATH)
@@ -38,3 +38,7 @@ CFLAGS+=-mfix-esp32-psram-cache-issue
CXXFLAGS+=-mfix-esp32-psram-cache-issue
endif
+# Enable dynamic esp_timer overflow value if building unit tests
+ifneq ("$(TEST_COMPONENTS_LIST)","")
+CPPFLAGS += -DESP_TIMER_DYNAMIC_OVERFLOW_VAL
+endif
diff --git a/components/esp32/clk.c b/components/esp32/clk.c
index 41b24c6ed9..4b1f0369c7 100644
--- a/components/esp32/clk.c
+++ b/components/esp32/clk.c
@@ -88,7 +88,7 @@ void esp_clk_init(void)
break;
default:
freq_mhz = 80;
- /* no break */
+ /* falls through */
case 80:
freq = RTC_CPU_FREQ_80M;
break;
@@ -128,7 +128,9 @@ static void select_rtc_slow_clk(rtc_slow_freq_t slow_clk)
{
uint32_t cal_val = 0;
uint32_t wait = 0;
- const uint32_t warning_timeout = 3 /* sec */ * 32768 /* Hz */ / (2 * SLOW_CLK_CAL_CYCLES);
+ uint32_t freq_hz = ((slow_clk == RTC_SLOW_FREQ_32K_XTAL) ? 32768 : 150000);
+ uint32_t warning_timeout = 3 /* sec */ * freq_hz /* Hz */ / (SLOW_CLK_CAL_CYCLES + 1);
+ warning_timeout = ((warning_timeout == 0) ? 3 /* sec */ : warning_timeout);
bool changing_clock_to_150k = false;
do {
if (slow_clk == RTC_SLOW_FREQ_32K_XTAL) {
@@ -141,11 +143,14 @@ static void select_rtc_slow_clk(rtc_slow_freq_t slow_clk)
*/
ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up");
rtc_clk_32k_enable(true);
- cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
- if(cal_val == 0 || cal_val < 15000000L){
- ESP_EARLY_LOGE(TAG, "RTC: Not found External 32 kHz XTAL. Switching to Internal 150 kHz RC chain");
- slow_clk = RTC_SLOW_FREQ_RTC;
- changing_clock_to_150k = true;
+ // When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
+ if (SLOW_CLK_CAL_CYCLES > 0) {
+ cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
+ if (cal_val == 0 || cal_val < 15000000L) {
+ ESP_EARLY_LOGE(TAG, "RTC: Not found External 32 kHz XTAL. Switching to Internal 150 kHz RC chain");
+ slow_clk = RTC_SLOW_FREQ_RTC;
+ changing_clock_to_150k = true;
+ }
}
}
rtc_clk_slow_freq_set(slow_clk);
diff --git a/components/esp32/component.mk b/components/esp32/component.mk
index fb53bfbb43..6c03587a36 100644
--- a/components/esp32/component.mk
+++ b/components/esp32/component.mk
@@ -13,6 +13,9 @@ endif
#specifies its own scripts.
LINKER_SCRIPTS += esp32.common.ld esp32.rom.ld esp32.peripherals.ld
+#Force pure functions from libgcc.a to be linked from ROM
+LINKER_SCRIPTS += esp32.rom.libgcc.ld
+
#SPI-RAM incompatible functions can be used in when the SPI RAM
#workaround is not enabled.
ifndef CONFIG_SPIRAM_CACHE_WORKAROUND
diff --git a/components/esp32/core_dump.c b/components/esp32/core_dump.c
index 56ce08b64a..078afe93ba 100644
--- a/components/esp32/core_dump.c
+++ b/components/esp32/core_dump.c
@@ -127,6 +127,10 @@ static void esp_core_dump_write(XtExcFrame *frame, core_dump_write_config_t *wri
if (tasks[i].pxTCB == xTaskGetCurrentTaskHandleForCPU(xPortGetCoreID())) {
// set correct stack top for current task
tasks[i].pxTopOfStack = (StackType_t *)frame;
+ // This field is not initialized for crashed task, but stack frame has the structure of interrupt one,
+ // so make workaround to allow espcoredump to parse it properly.
+ if (frame->exit == 0)
+ frame->exit = -1;
ESP_COREDUMP_LOG_PROCESS("Current task EXIT/PC/PS/A0/SP %x %x %x %x %x",
frame->exit, frame->pc, frame->ps, frame->a0, frame->a1);
}
diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c
index 4d907f333c..bf044bd7b2 100644
--- a/components/esp32/cpu_start.c
+++ b/components/esp32/cpu_start.c
@@ -29,6 +29,7 @@
#include "soc/io_mux_reg.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/timer_group_reg.h"
+#include "soc/rtc_wdt.h"
#include "driver/rtc_io.h"
@@ -136,7 +137,7 @@ void IRAM_ATTR call_start_cpu0()
|| rst_reas[1] == RTCWDT_SYS_RESET || rst_reas[1] == TG0WDT_SYS_RESET
#endif
) {
- esp_panic_wdt_stop();
+ rtc_wdt_disable();
}
//Clear BSS. Please do not attempt to do any complex stuff (like early logging) before this.
@@ -269,13 +270,6 @@ void start_cpu0_default(void)
ESP_EARLY_LOGE(TAG, "External RAM could not be added to heap!");
abort();
}
-#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL
- r=esp_spiram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL);
- if (r != ESP_OK) {
- ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool!");
- abort();
- }
-#endif
#if CONFIG_SPIRAM_USE_MALLOC
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
#endif
@@ -435,7 +429,7 @@ static void main_task(void* args)
{
// Now that the application is about to start, disable boot watchdogs
REG_CLR_BIT(TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN_S);
- REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN);
+ rtc_wdt_disable();
#if !CONFIG_FREERTOS_UNICORE
// Wait for FreeRTOS initialization to finish on APP CPU, before replacing its startup stack
while (port_xSchedulerRunning[1] == 0) {
@@ -445,6 +439,15 @@ static void main_task(void* args)
//Enable allocation in region where the startup stacks were located.
heap_caps_enable_nonos_stack_heaps();
+ // Now we have startup stack RAM available for heap, enable any DMA pool memory
+#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL
+ esp_err_t r = esp_spiram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL);
+ if (r != ESP_OK) {
+ ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool (error 0x%x)", r);
+ abort();
+ }
+#endif
+
//Initialize task wdt if configured to do so
#ifdef CONFIG_TASK_WDT_PANIC
ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_TASK_WDT_TIMEOUT_S, true))
diff --git a/components/esp32/crosscore_int.c b/components/esp32/crosscore_int.c
index 9ccda1f824..18a5237b5a 100644
--- a/components/esp32/crosscore_int.c
+++ b/components/esp32/crosscore_int.c
@@ -44,7 +44,7 @@ static volatile uint32_t reason[ portNUM_PROCESSORS ];
ToDo: There is a small chance the CPU already has yielded when this ISR is serviced. In that case, it's running the intended task but
the ISR will cause it to switch _away_ from it. portYIELD_FROM_ISR will probably just schedule the task again, but have to check that.
*/
-static void esp_crosscore_isr_handle_yield()
+static inline void IRAM_ATTR esp_crosscore_isr_handle_yield()
{
portYIELD_FROM_ISR();
}
diff --git a/components/esp32/dport_panic_highint_hdl.S b/components/esp32/dport_panic_highint_hdl.S
index ffd3b45f11..bddde3cdff 100644
--- a/components/esp32/dport_panic_highint_hdl.S
+++ b/components/esp32/dport_panic_highint_hdl.S
@@ -16,7 +16,6 @@
#include
#include
#include
-#include
#include "freertos/xtensa_context.h"
#include "esp_panic.h"
#include "sdkconfig.h"
diff --git a/components/esp32/esp_err_to_name.c b/components/esp32/esp_err_to_name.c
index b6743c31ea..7b74704e01 100644
--- a/components/esp32/esp_err_to_name.c
+++ b/components/esp32/esp_err_to_name.c
@@ -37,6 +37,9 @@
#if __has_include("esp_wps.h")
#include "esp_wps.h"
#endif
+#if __has_include("http_server.h")
+#include "http_server.h"
+#endif
#if __has_include("nvs.h")
#include "nvs.h"
#endif
@@ -55,43 +58,43 @@ typedef struct {
static const esp_err_msg_t esp_err_msg_table[] = {
// components/esp32/include/esp_err.h
# ifdef ESP_FAIL
- ERR_TBL_IT(ESP_FAIL), /* -1 */
+ ERR_TBL_IT(ESP_FAIL), /* -1 Generic esp_err_t code indicating failure */
# endif
# ifdef ESP_OK
- ERR_TBL_IT(ESP_OK), /* 0 */
+ ERR_TBL_IT(ESP_OK), /* 0 esp_err_t value indicating success (no error) */
# endif
# ifdef ESP_ERR_NO_MEM
- ERR_TBL_IT(ESP_ERR_NO_MEM), /* 257 0x101 */
+ ERR_TBL_IT(ESP_ERR_NO_MEM), /* 257 0x101 Out of memory */
# endif
# ifdef ESP_ERR_INVALID_ARG
- ERR_TBL_IT(ESP_ERR_INVALID_ARG), /* 258 0x102 */
+ ERR_TBL_IT(ESP_ERR_INVALID_ARG), /* 258 0x102 Invalid argument */
# endif
# ifdef ESP_ERR_INVALID_STATE
- ERR_TBL_IT(ESP_ERR_INVALID_STATE), /* 259 0x103 */
+ ERR_TBL_IT(ESP_ERR_INVALID_STATE), /* 259 0x103 Invalid state */
# endif
# ifdef ESP_ERR_INVALID_SIZE
- ERR_TBL_IT(ESP_ERR_INVALID_SIZE), /* 260 0x104 */
+ ERR_TBL_IT(ESP_ERR_INVALID_SIZE), /* 260 0x104 Invalid size */
# endif
# ifdef ESP_ERR_NOT_FOUND
- ERR_TBL_IT(ESP_ERR_NOT_FOUND), /* 261 0x105 */
+ ERR_TBL_IT(ESP_ERR_NOT_FOUND), /* 261 0x105 Requested resource not found */
# endif
# ifdef ESP_ERR_NOT_SUPPORTED
- ERR_TBL_IT(ESP_ERR_NOT_SUPPORTED), /* 262 0x106 */
+ ERR_TBL_IT(ESP_ERR_NOT_SUPPORTED), /* 262 0x106 Operation or feature not supported */
# endif
# ifdef ESP_ERR_TIMEOUT
- ERR_TBL_IT(ESP_ERR_TIMEOUT), /* 263 0x107 */
+ ERR_TBL_IT(ESP_ERR_TIMEOUT), /* 263 0x107 Operation timed out */
# endif
# ifdef ESP_ERR_INVALID_RESPONSE
- ERR_TBL_IT(ESP_ERR_INVALID_RESPONSE), /* 264 0x108 */
+ ERR_TBL_IT(ESP_ERR_INVALID_RESPONSE), /* 264 0x108 Received response was invalid */
# endif
# ifdef ESP_ERR_INVALID_CRC
- ERR_TBL_IT(ESP_ERR_INVALID_CRC), /* 265 0x109 */
+ ERR_TBL_IT(ESP_ERR_INVALID_CRC), /* 265 0x109 CRC or checksum was invalid */
# endif
# ifdef ESP_ERR_INVALID_VERSION
- ERR_TBL_IT(ESP_ERR_INVALID_VERSION), /* 266 0x10a */
+ ERR_TBL_IT(ESP_ERR_INVALID_VERSION), /* 266 0x10a Version was invalid */
# endif
# ifdef ESP_ERR_INVALID_MAC
- ERR_TBL_IT(ESP_ERR_INVALID_MAC), /* 267 0x10b */
+ ERR_TBL_IT(ESP_ERR_INVALID_MAC), /* 267 0x10b MAC address was invalid */
# endif
// components/nvs_flash/include/nvs.h
# ifdef ESP_ERR_NVS_BASE
@@ -132,7 +135,7 @@ static const esp_err_msg_t esp_err_msg_table[] = {
ERR_TBL_IT(ESP_ERR_NVS_KEY_TOO_LONG), /* 4361 0x1109 Key name is too long */
# endif
# ifdef ESP_ERR_NVS_PAGE_FULL
- ERR_TBL_IT(ESP_ERR_NVS_PAGE_FULL), /* 4362 0x110a Internal error; never returned by nvs_ API
+ ERR_TBL_IT(ESP_ERR_NVS_PAGE_FULL), /* 4362 0x110a Internal error; never returned by nvs API
functions */
# endif
# ifdef ESP_ERR_NVS_INVALID_STATE
@@ -157,6 +160,11 @@ static const esp_err_msg_t esp_err_msg_table[] = {
# ifdef ESP_ERR_NVS_PART_NOT_FOUND
ERR_TBL_IT(ESP_ERR_NVS_PART_NOT_FOUND), /* 4367 0x110f Partition with specified name is not found
in the partition table */
+# endif
+# ifdef ESP_ERR_NVS_NEW_VERSION_FOUND
+ ERR_TBL_IT(ESP_ERR_NVS_NEW_VERSION_FOUND), /* 4368 0x1110 NVS partition contains data in new format
+ and cannot be recognized by this version of
+ code */
# endif
// components/ulp/include/esp32/ulp.h
# ifdef ESP_ERR_ULP_BASE
@@ -420,6 +428,37 @@ static const esp_err_msg_t esp_err_msg_table[] = {
# ifdef ESP_ERR_HTTP_INVALID_TRANSPORT
ERR_TBL_IT(ESP_ERR_HTTP_INVALID_TRANSPORT), /* 28677 0x7005 There are no transport support for the input
scheme */
+# endif
+ // components/http_server/include/http_server.h
+# ifdef ESP_ERR_HTTPD_BASE
+ ERR_TBL_IT(ESP_ERR_HTTPD_BASE), /* 32768 0x8000 Starting number of HTTPD error codes */
+# endif
+# ifdef ESP_ERR_HTTPD_HANDLERS_FULL
+ ERR_TBL_IT(ESP_ERR_HTTPD_HANDLERS_FULL), /* 32769 0x8001 All slots for registering URI handlers have
+ been consumed */
+# endif
+# ifdef ESP_ERR_HTTPD_HANDLER_EXISTS
+ ERR_TBL_IT(ESP_ERR_HTTPD_HANDLER_EXISTS), /* 32770 0x8002 URI handler with same method and target URI
+ already registered */
+# endif
+# ifdef ESP_ERR_HTTPD_INVALID_REQ
+ ERR_TBL_IT(ESP_ERR_HTTPD_INVALID_REQ), /* 32771 0x8003 Invalid request pointer */
+# endif
+# ifdef ESP_ERR_HTTPD_RESULT_TRUNC
+ ERR_TBL_IT(ESP_ERR_HTTPD_RESULT_TRUNC), /* 32772 0x8004 Result string truncated */
+# endif
+# ifdef ESP_ERR_HTTPD_RESP_HDR
+ ERR_TBL_IT(ESP_ERR_HTTPD_RESP_HDR), /* 32773 0x8005 Response header field larger than supported */
+# endif
+# ifdef ESP_ERR_HTTPD_RESP_SEND
+ ERR_TBL_IT(ESP_ERR_HTTPD_RESP_SEND), /* 32774 0x8006 Error occured while sending response packet */
+# endif
+# ifdef ESP_ERR_HTTPD_ALLOC_MEM
+ ERR_TBL_IT(ESP_ERR_HTTPD_ALLOC_MEM), /* 32775 0x8007 Failed to dynamically allocate memory for
+ resource */
+# endif
+# ifdef ESP_ERR_HTTPD_TASK
+ ERR_TBL_IT(ESP_ERR_HTTPD_TASK), /* 32776 0x8008 Failed to launch server task/thread */
# endif
// components/spi_flash/include/esp_spi_flash.h
# ifdef ESP_ERR_FLASH_BASE
@@ -473,7 +512,7 @@ const char *esp_err_to_name_r(esp_err_t code, char *buf, size_t buflen)
return buf;
}
- snprintf(buf, buflen, "Unknown error %d", code);
+ snprintf(buf, buflen, "%s 0x%x(%d)", esp_unknown_msg, code, code);
return buf;
}
diff --git a/components/esp32/esp_err_to_name.c.in b/components/esp32/esp_err_to_name.c.in
index b6b87312e9..5f623c62dc 100644
--- a/components/esp32/esp_err_to_name.c.in
+++ b/components/esp32/esp_err_to_name.c.in
@@ -58,7 +58,7 @@ const char *esp_err_to_name_r(esp_err_t code, char *buf, size_t buflen)
return buf;
}
- snprintf(buf, buflen, "Unknown error %d", code);
+ snprintf(buf, buflen, "%s 0x%x(%d)", esp_unknown_msg, code, code);
return buf;
}
diff --git a/components/esp32/esp_timer_esp32.c b/components/esp32/esp_timer_esp32.c
index b2c29721b2..d42c8cfdc6 100644
--- a/components/esp32/esp_timer_esp32.c
+++ b/components/esp32/esp_timer_esp32.c
@@ -82,7 +82,18 @@
* ISR happens follow set_alarm, so change the ALARM_OVERFLOW_VAL to resolve this problem.
* Set it to 0xefffffffUL. The remain 0x10000000UL(about 3 second) is enough to handle ISR.
*/
-#define ALARM_OVERFLOW_VAL 0xefffffffUL
+#define DEFAULT_ALARM_OVERFLOW_VAL 0xefffffffUL
+
+/* Provision to set lower overflow value for unit testing. Lowering the
+ * overflow value helps check for race conditions which occur near overflow
+ * moment.
+ */
+#ifndef ESP_TIMER_DYNAMIC_OVERFLOW_VAL
+#define ALARM_OVERFLOW_VAL DEFAULT_ALARM_OVERFLOW_VAL
+#else
+static uint32_t s_alarm_overflow_val = DEFAULT_ALARM_OVERFLOW_VAL;
+#define ALARM_OVERFLOW_VAL (s_alarm_overflow_val)
+#endif
static const char* TAG = "esp_timer_impl";
@@ -190,7 +201,7 @@ uint64_t IRAM_ATTR esp_timer_impl_get_time()
ticks_per_us = s_timer_ticks_per_us;
/* Read them again and compare */
- /* In this function, do not call timer_count_reload() when overflow is ture.
+ /* In this function, do not call timer_count_reload() when overflow is true.
* Because there's remain count enough to allow FRC_TIMER_COUNT_REG grow
*/
if (REG_READ(FRC_TIMER_COUNT_REG(1)) > timer_val &&
@@ -216,18 +227,6 @@ void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
// Adjust current time if overflow has happened
bool overflow = timer_overflow_happened();
uint64_t cur_count = REG_READ(FRC_TIMER_COUNT_REG(1));
- uint32_t offset = s_timer_ticks_per_us * 2; //remain 2us for more safe
-
- //If overflow is going to happen in 1us, let's wait until it happens,
- //else we think it will not happen before new alarm set.
- //And we should wait current timer count less than ALARM_OVERFLOW_VAL,
- //maybe equals to 0.
- if (cur_count + offset >= ALARM_OVERFLOW_VAL) {
- do {
- overflow = timer_overflow_happened();
- cur_count = REG_READ(FRC_TIMER_COUNT_REG(1));
- } while(!overflow || cur_count == ALARM_OVERFLOW_VAL);
- }
if (overflow) {
assert(time_after_timebase_us > s_timer_us_per_overflow);
@@ -237,13 +236,17 @@ void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
// Calculate desired timer compare value (may exceed 2^32-1)
uint64_t compare_val = time_after_timebase_us * s_timer_ticks_per_us;
uint32_t alarm_reg_val = ALARM_OVERFLOW_VAL;
- // Use calculated alarm value if it is less than 2^32-1
+ // Use calculated alarm value if it is less than ALARM_OVERFLOW_VAL.
+ // Note that if by the time we update ALARM_REG, COUNT_REG value is higher,
+ // interrupt will not happen for another ALARM_OVERFLOW_VAL timer ticks,
+ // so need to check if alarm value is too close in the future (e.g. <2 us away).
+ const uint32_t offset = s_timer_ticks_per_us * 2;
if (compare_val < ALARM_OVERFLOW_VAL) {
- // If we by the time we update ALARM_REG, COUNT_REG value is higher,
- // interrupt will not happen for another 2^32 timer ticks, so need to
- // check if alarm value is too close in the future (e.g. <1 us away).
if (compare_val < cur_count + offset) {
compare_val = cur_count + offset;
+ if (compare_val > ALARM_OVERFLOW_VAL) {
+ compare_val = ALARM_OVERFLOW_VAL;
+ }
}
alarm_reg_val = (uint32_t) compare_val;
}
@@ -387,3 +390,17 @@ uint64_t IRAM_ATTR esp_timer_impl_get_min_period_us()
{
return 50;
}
+
+#ifdef ESP_TIMER_DYNAMIC_OVERFLOW_VAL
+uint32_t esp_timer_impl_get_overflow_val()
+{
+ return s_alarm_overflow_val;
+}
+
+void esp_timer_impl_set_overflow_val(uint32_t overflow_val)
+{
+ s_alarm_overflow_val = overflow_val;
+ /* update alarm value */
+ esp_timer_impl_update_apb_freq(esp_clk_apb_freq() / 1000000);
+}
+#endif // ESP_TIMER_DYNAMIC_OVERFLOW_VAL
diff --git a/components/esp32/fast_crypto_ops.c b/components/esp32/fast_crypto_ops.c
index aa0054d707..7e05a7b8c9 100644
--- a/components/esp32/fast_crypto_ops.c
+++ b/components/esp32/fast_crypto_ops.c
@@ -36,6 +36,8 @@
* we recommend, so as the API in WPS default and WPA2 default.
*/
const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs = {
+ .size = sizeof(wpa_crypto_funcs_t),
+ .version = ESP_WIFI_CRYPTO_VERSION,
.aes_wrap = (esp_aes_wrap_t)fast_aes_wrap,
.aes_unwrap = (esp_aes_unwrap_t)fast_aes_unwrap,
.hmac_sha256_vector = (esp_hmac_sha256_vector_t)fast_hmac_sha256_vector,
@@ -58,6 +60,8 @@ const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs = {
};
const wps_crypto_funcs_t g_wifi_default_wps_crypto_funcs = {
+ .size = sizeof(wps_crypto_funcs_t),
+ .version = ESP_WIFI_CRYPTO_VERSION,
.aes_128_encrypt = (esp_aes_128_encrypt_t)fast_aes_128_cbc_encrypt,
.aes_128_decrypt = (esp_aes_128_decrypt_t)fast_aes_128_cbc_decrypt,
.crypto_mod_exp = (esp_crypto_mod_exp_t)fast_crypto_mod_exp,
@@ -85,6 +89,8 @@ const wps_crypto_funcs_t g_wifi_default_wps_crypto_funcs = {
* crypto_hash_finish, so do crypto_cipher.
*/
const wpa2_crypto_funcs_t g_wifi_default_wpa2_crypto_funcs = {
+ .size = sizeof(wpa2_crypto_funcs_t),
+ .version = ESP_WIFI_CRYPTO_VERSION,
.crypto_hash_init = (esp_crypto_hash_init_t)fast_crypto_hash_init,
.crypto_hash_update = (esp_crypto_hash_update_t)fast_crypto_hash_update,
.crypto_hash_finish = (esp_crypto_hash_finish_t)fast_crypto_hash_finish,
@@ -100,6 +106,8 @@ const wpa2_crypto_funcs_t g_wifi_default_wpa2_crypto_funcs = {
.eap_peer_blob_deinit = (esp_eap_peer_blob_deinit_t)eap_peer_blob_deinit,
.eap_peer_config_init = (esp_eap_peer_config_init_t)eap_peer_config_init,
.eap_peer_config_deinit = (esp_eap_peer_config_deinit_t)eap_peer_config_deinit,
+ .eap_peer_register_methods = (esp_eap_peer_register_methods_t)eap_peer_register_methods,
+ .eap_peer_unregister_methods = (esp_eap_peer_unregister_methods_t)eap_peer_unregister_methods,
.eap_deinit_prev_method = (esp_eap_deinit_prev_method_t)eap_deinit_prev_method,
.eap_peer_get_eap_method = (esp_eap_peer_get_eap_method_t)eap_peer_get_eap_method,
.eap_sm_abort = (esp_eap_sm_abort_t)eap_sm_abort,
diff --git a/components/esp32/include/esp_attr.h b/components/esp32/include/esp_attr.h
index a9c3f9a7a3..5bf9a22926 100644
--- a/components/esp32/include/esp_attr.h
+++ b/components/esp32/include/esp_attr.h
@@ -47,4 +47,12 @@
// Forces read-only data into RTC slow memory. See "docs/deep-sleep-stub.rst"
#define RTC_RODATA_ATTR __attribute__((section(".rtc.rodata")))
+// Forces data into noinit section to avoid initialization after restart.
+#define __NOINIT_ATTR __attribute__((section(".noinit")))
+
+// Forces data into RTC slow memory of .noinit section.
+// Any variable marked with this attribute will keep its value
+// after restart or during a deep sleep / wake cycle.
+#define RTC_NOINIT_ATTR __attribute__((section(".rtc_noinit")))
+
#endif /* __ESP_ATTR_H__ */
diff --git a/components/esp32/include/esp_err.h b/components/esp32/include/esp_err.h
index b38a723bc3..d8820e5ae1 100644
--- a/components/esp32/include/esp_err.h
+++ b/components/esp32/include/esp_err.h
@@ -24,21 +24,20 @@ extern "C" {
typedef int32_t esp_err_t;
/* Definitions for error constants. */
+#define ESP_OK 0 /*!< esp_err_t value indicating success (no error) */
+#define ESP_FAIL -1 /*!< Generic esp_err_t code indicating failure */
-#define ESP_OK 0
-#define ESP_FAIL -1
-
-#define ESP_ERR_NO_MEM 0x101
-#define ESP_ERR_INVALID_ARG 0x102
-#define ESP_ERR_INVALID_STATE 0x103
-#define ESP_ERR_INVALID_SIZE 0x104
-#define ESP_ERR_NOT_FOUND 0x105
-#define ESP_ERR_NOT_SUPPORTED 0x106
-#define ESP_ERR_TIMEOUT 0x107
-#define ESP_ERR_INVALID_RESPONSE 0x108
-#define ESP_ERR_INVALID_CRC 0x109
-#define ESP_ERR_INVALID_VERSION 0x10A
-#define ESP_ERR_INVALID_MAC 0x10B
+#define ESP_ERR_NO_MEM 0x101 /*!< Out of memory */
+#define ESP_ERR_INVALID_ARG 0x102 /*!< Invalid argument */
+#define ESP_ERR_INVALID_STATE 0x103 /*!< Invalid state */
+#define ESP_ERR_INVALID_SIZE 0x104 /*!< Invalid size */
+#define ESP_ERR_NOT_FOUND 0x105 /*!< Requested resource not found */
+#define ESP_ERR_NOT_SUPPORTED 0x106 /*!< Operation or feature not supported */
+#define ESP_ERR_TIMEOUT 0x107 /*!< Operation timed out */
+#define ESP_ERR_INVALID_RESPONSE 0x108 /*!< Received response was invalid */
+#define ESP_ERR_INVALID_CRC 0x109 /*!< CRC or checksum was invalid */
+#define ESP_ERR_INVALID_VERSION 0x10A /*!< Version was invalid */
+#define ESP_ERR_INVALID_MAC 0x10B /*!< MAC address was invalid */
#define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */
#define ESP_ERR_MESH_BASE 0x4000 /*!< Starting number of MESH error codes */
@@ -76,6 +75,7 @@ const char *esp_err_to_name(esp_err_t code);
*/
const char *esp_err_to_name_r(esp_err_t code, char *buf, size_t buflen);
+/** @cond */
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) __attribute__((noreturn));
#ifndef __ASSERT_FUNC
@@ -88,6 +88,7 @@ void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const cha
#define __ASSERT_FUNC "??"
#endif
#endif
+/** @endcond */
/**
* Macro which can be used to check the error code,
diff --git a/components/esp32/include/esp_flash_data_types.h b/components/esp32/include/esp_flash_data_types.h
index 3e44b2639d..bb5aa2998a 100644
--- a/components/esp32/include/esp_flash_data_types.h
+++ b/components/esp32/include/esp_flash_data_types.h
@@ -21,7 +21,6 @@ extern "C"
{
#endif
-#define ESP_PARTITION_TABLE_ADDR 0x8000
#define ESP_PARTITION_MAGIC 0x50AA
#define ESP_PARTITION_MAGIC_MD5 0xEBEB
diff --git a/components/esp32/include/esp_mesh.h b/components/esp32/include/esp_mesh.h
index 14bd21f7ea..8fea167de1 100644
--- a/components/esp32/include/esp_mesh.h
+++ b/components/esp32/include/esp_mesh.h
@@ -936,7 +936,7 @@ bool esp_mesh_get_self_organized(void);
* be expected to find to replace the current one.
* If no desired root candidate, the vote will try a specified attempts(at least 10 times), if no better
* root candidate is found, keep the current one. If a better candidate is found, the new better one will
- * send a root switch request to the current root, current root will respond with a root switch acknowledgement.
+ * send a root switch request to the current root, current root will respond with a root switch acknowledgment.
* After that, the new candidate will connect to the router to be a new root, the previous root will disconnect
* with the router and choose another parent instead.
* So far, root switch is completed with minimal disruption to the whole mesh network.
@@ -951,6 +951,8 @@ bool esp_mesh_get_self_organized(void);
*
* @return
* - ESP_OK
+ * - ESP_ERR_MESH_QUEUE_FULL
+ * - ESP_ERR_MESH_DISCARD
* - ESP_FAIL
*/
esp_err_t esp_mesh_waive_root(const mesh_vote_t *vote, int reason);
@@ -1310,6 +1312,14 @@ esp_err_t esp_mesh_scan_get_ap_ie_len(int *len);
*/
esp_err_t esp_mesh_scan_get_ap_record(wifi_ap_record_t *ap_record, void *buffer);
+/**
+ * @brief flush upstream packets pending in to_parent queue and to_parent_p2p queue
+ *
+ * @return
+ * - ESP_OK
+ */
+esp_err_t esp_mesh_flush_upstream_packets(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/components/esp32/include/esp_mesh_internal.h b/components/esp32/include/esp_mesh_internal.h
index da349297eb..5f73984a1a 100644
--- a/components/esp32/include/esp_mesh_internal.h
+++ b/components/esp32/include/esp_mesh_internal.h
@@ -33,22 +33,31 @@ extern "C" {
* Structures
*******************************************************/
typedef struct {
- int scan; /**< minimum scan times before being a root, default:10 */
- int vote; /**< max vote times in self-healing, default:10000 */
- int fail; /**< parent selection fail times, if the scan times reach this value,
- will disconnect with associated children and join self-healing. default:60 */
- int monitor_ie; /**< acceptable times of parent ie change before update self ie, default:3 */
+ int scan; /**< minimum scan times before being a root, default:10. */
+ int vote; /**< max vote times in self-healing, default:1000. */
+ int fail; /**< parent selection fail times. If the scan times reach this value,
+ device will disconnect with associated children and join self-healing, default:120. */
+ int monitor_ie; /**< acceptable times of parent networking IE change before update self networking IE, default:10. */
} mesh_attempts_t;
typedef struct {
- int duration_ms; /* parent weak RSSI monitor duration, if the RSSI continues to be weak during this duration_ms,
- will switch to a better parent */
- int cnx_rssi; /* RSSI threshold for keeping a good connection with parent */
- int select_rssi; /* RSSI threshold for parent selection, should be a value greater than switch_rssi */
- int switch_rssi; /* RSSI threshold for action to reselect a better parent */
+ int duration_ms; /* parent weak RSSI monitor duration. If the RSSI with current parent is less than cnx_rssi continuously
+ within this duration_ms, device will search for a better parent. */
+ int cnx_rssi; /* RSSI threshold for keeping a good connection with parent.
+ If set a value greater than -120 dBm, device will arm a timer to monitor current RSSI at a period time of
+ duration_ms. */
+ int select_rssi; /* RSSI threshold for parent selection, should be a value greater than switch_rssi. */
+ int switch_rssi; /* RSSI threshold for parent switch. Device will disassociate current parent and switch to a new parent when
+ the RSSI with the new parent is greater than this set threshold. */
int backoff_rssi; /* RSSI threshold for connecting to the root */
} mesh_switch_parent_t;
+typedef struct {
+ int high;
+ int medium;
+ int low;
+} mesh_rssi_threshold_t;
+
/**
* @brief mesh networking IE
*/
@@ -58,8 +67,8 @@ typedef struct {
uint8_t len; /**< element length */
uint8_t oui[3]; /**< organization identifier */
/**< mesh networking IE content */
- uint8_t type; /** mesh networking IE type */
- uint8_t encryped : 1; /**< if mesh networking IE is encrypted */
+ uint8_t type; /** ESP defined IE type */
+ uint8_t encryped : 1; /**< whether mesh networking IE is encrypted */
uint8_t version : 7; /**< mesh networking IE version */
/**< content */
uint8_t mesh_type; /**< mesh device type */
@@ -74,13 +83,13 @@ typedef struct {
uint16_t self_cap; /**< self capacity */
uint16_t layer2_cap; /**< layer2 capacity */
uint16_t scan_ap_num; /**< the number of scanned APs */
- int8_t rssi; /**< rssi of the parent */
- int8_t router_rssi; /**< rssi of the router */
+ int8_t rssi; /**< RSSI of the parent */
+ int8_t router_rssi; /**< RSSI of the router */
uint8_t flag; /**< flag of networking */
uint8_t rc_addr[6]; /**< root address */
- int8_t rc_rssi; /**< root rssi */
+ int8_t rc_rssi; /**< root RSSI */
uint8_t vote_addr[6]; /**< voter address */
- int8_t vote_rssi; /**< vote rssi of the router */
+ int8_t vote_rssi; /**< vote RSSI of the router */
uint8_t vote_ttl; /**< vote ttl */
uint16_t votes; /**< votes */
uint16_t my_votes; /**< my votes */
@@ -115,9 +124,9 @@ esp_err_t esp_mesh_set_beacon_interval(int interval_ms);
esp_err_t esp_mesh_get_beacon_interval(int *interval_ms);
/**
- * @brief set attempts for mesh self-organized networking
+ * @brief set attempts for mesh self-organized networking
*
- * @param attempts
+ * @param attempts
*
* @return
* - ESP_OK
@@ -132,7 +141,7 @@ esp_err_t esp_mesh_set_attempts(mesh_attempts_t *attempts);
*
* @return
* - ESP_OK
- * - ESP_FAIL
+ * - ESP_ERR_MESH_ARGUMENT
*/
esp_err_t esp_mesh_get_attempts(mesh_attempts_t *attempts);
@@ -143,7 +152,7 @@ esp_err_t esp_mesh_get_attempts(mesh_attempts_t *attempts);
*
* @return
* - ESP_OK
- * - ESP_FAIL
+ * - ESP_ERR_MESH_ARGUMENT
*/
esp_err_t esp_mesh_set_switch_parent_paras(mesh_switch_parent_t *paras);
@@ -154,10 +163,46 @@ esp_err_t esp_mesh_set_switch_parent_paras(mesh_switch_parent_t *paras);
*
* @return
* - ESP_OK
- * - ESP_FAIL
+ * - ESP_ERR_MESH_ARGUMENT
*/
esp_err_t esp_mesh_get_switch_parent_paras(mesh_switch_parent_t *paras);
+/**
+ * @brief set RSSI threshold
+ * The default high RSSI threshold value is -78 dBm.
+ * The default medium RSSI threshold value is -82 dBm.
+ * The default low RSSI threshold value is -85 dBm.
+ *
+ * @param threshold RSSI threshold
+ *
+ * @return
+ * - ESP_OK
+ * - ESP_ERR_MESH_ARGUMENT
+ */
+esp_err_t esp_mesh_set_rssi_threshold(const mesh_rssi_threshold_t *threshold);
+
+/**
+ * @brief get RSSI threshold
+ * @param threshold RSSI threshold
+ *
+ * @return
+ * - ESP_OK
+ * - ESP_ERR_MESH_ARGUMENT
+ */
+esp_err_t esp_mesh_get_rssi_threshold(mesh_rssi_threshold_t *threshold);
+
+/**
+ * @brief enable the minimum rate to 6Mbps
+ *
+ * @attention This API shall be called before WiFi start.
+ *
+ * @param is_6m enable or not
+ *
+ * @return
+ * - ESP_OK
+ */
+esp_err_t esp_mesh_set_6m_rate(bool is_6m);
+
/**
* @brief print the number of txQ waiting
*
@@ -195,6 +240,29 @@ esp_err_t esp_mesh_set_passive_scan_time(int time_ms);
*/
int esp_mesh_get_passive_scan_time(void);
+/**
+ * @brief set announce interval
+ * The default short interval is 500 milliseconds.
+ * The default long interval is 3000 milliseconds.
+ *
+ * @param short_ms shall be greater than the default value
+ * @param long_ms shall be greater than the default value
+ *
+ * @return
+ * - ESP_OK
+ */
+esp_err_t esp_mesh_set_announce_interval(int short_ms, int long_ms);
+
+/**
+ * @brief get announce interval
+ *
+ * @param short_ms short interval
+ * @param long_ms long interval
+ *
+ * @return
+ * - ESP_OK
+ */
+esp_err_t esp_mesh_get_announce_interval(int *short_ms, int *long_ms);
#ifdef __cplusplus
}
diff --git a/components/esp32/include/esp_panic.h b/components/esp32/include/esp_panic.h
index 4e0630a245..b9e192f046 100644
--- a/components/esp32/include/esp_panic.h
+++ b/components/esp32/include/esp_panic.h
@@ -61,12 +61,6 @@ esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags);
*/
void esp_clear_watchpoint(int no);
-
-/**
- * @brief Stops panic WDT
- */
-void esp_panic_wdt_stop(void);
-
/**
* @brief Checks stack pointer
*/
diff --git a/components/esp32/include/esp_phy_init.h b/components/esp32/include/esp_phy_init.h
index 0228edf1cf..f06375d1a6 100644
--- a/components/esp32/include/esp_phy_init.h
+++ b/components/esp32/include/esp_phy_init.h
@@ -58,6 +58,7 @@ typedef enum{
MODEM_WIFI_STATION_MODULE, //!< Wi-Fi Station used
MODEM_WIFI_SOFTAP_MODULE, //!< Wi-Fi SoftAP used
MODEM_WIFI_SNIFFER_MODULE, //!< Wi-Fi Sniffer used
+ MODEM_WIFI_NULL_MODULE, //!< Wi-Fi Null mode used
MODEM_USER_MODULE, //!< User used
MODEM_MODULE_COUNT //!< Number of items
}modem_sleep_module_t;
@@ -73,7 +74,8 @@ typedef enum{
*/
#define MODEM_WIFI_MASK ((1<
#include
+#include
#include "esp_err.h"
+typedef enum {
+ ESP_SPIRAM_VOLT_3V3 = 0, /*!< SPI RAM voltage is 3.3v */
+ ESP_SPIRAM_VOLT_1V8 = 1, /*!< SPI RAM voltage is 1.8v */
+ ESP_SPIRAM_VOLT_INVALID, /*!< SPI RAM voltage is invalid*/
+} esp_spiram_volt_t;
+
+typedef enum {
+ ESP_SPIRAM_SIZE_32MBITS = 0, /*!< SPI RAM size is 32 MBits */
+ ESP_SPIRAM_SIZE_64MBITS = 1, /*!< SPI RAM size is 64 MBits */
+ ESP_SPIRAM_SIZE_INVALID, /*!< SPI RAM size is invalid */
+} esp_spiram_size_t;
+
+/**
+ * @brief get SPI RAM voltage
+ * @return
+ * - ESP_SPIRAM_VOLT_INVALID if SPI RAM not enabled or not valid.
+ * - SPI RAM voltage
+ */
+esp_spiram_volt_t esp_spiram_get_chip_volt();
+
+/**
+ * @brief get SPI RAM size
+ * @return
+ * - ESP_SPIRAM_SIZE_INVALID if SPI RAM not enabled or not valid
+ * - SPI RAM size
+ */
+esp_spiram_size_t esp_spiram_get_chip_size();
+
/**
* @brief Initialize spiram interface/hardware. Normally called from cpu_start.c.
*
diff --git a/components/esp32/include/esp_wifi.h b/components/esp32/include/esp_wifi.h
index daaa14f89d..d4c11c3870 100644
--- a/components/esp32/include/esp_wifi.h
+++ b/components/esp32/include/esp_wifi.h
@@ -428,24 +428,24 @@ esp_err_t esp_wifi_scan_get_ap_records(uint16_t *number, wifi_ap_record_t *ap_re
esp_err_t esp_wifi_sta_get_ap_info(wifi_ap_record_t *ap_info);
/**
- * @brief Set current power save type
+ * @brief Set current WiFi power save type
*
- * @attention Default power save type is WIFI_PS_NONE.
+ * @attention Default power save type is WIFI_PS_MIN_MODEM.
*
* @param type power save type
*
- * @return ESP_ERR_NOT_SUPPORTED: not supported yet
+ * @return ESP_OK: succeed
*/
esp_err_t esp_wifi_set_ps(wifi_ps_type_t type);
/**
- * @brief Get current power save type
+ * @brief Get current WiFi power save type
*
- * @attention Default power save type is WIFI_PS_NONE.
+ * @attention Default power save type is WIFI_PS_MIN_MODEM.
*
* @param[out] type: store current power save type
*
- * @return ESP_ERR_NOT_SUPPORTED: not supported yet
+ * @return ESP_OK: succeed
*/
esp_err_t esp_wifi_get_ps(wifi_ps_type_t *type);
@@ -981,7 +981,7 @@ esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len, b
* Each time a CSI data is received, the callback function will be called.
*
* @param ctx context argument, passed to esp_wifi_set_csi_rx_cb() when registering callback function.
- * @param data CSI data received.
+ * @param data CSI data received. The memory that it points to will be deallocated after callback function returns.
*
*/
typedef void (* wifi_csi_cb_t)(void *ctx, wifi_csi_info_t *data);
diff --git a/components/esp32/include/esp_wifi_crypto_types.h b/components/esp32/include/esp_wifi_crypto_types.h
index 2e605d870c..e1e2a51a13 100644
--- a/components/esp32/include/esp_wifi_crypto_types.h
+++ b/components/esp32/include/esp_wifi_crypto_types.h
@@ -27,6 +27,8 @@
extern "C" {
#endif
+#define ESP_WIFI_CRYPTO_VERSION 0x00000001
+
/*
* Enumeration for hash operations.
* When WPA2 is connecting, this enum is used to
@@ -605,7 +607,7 @@ typedef void (*esp_uuid_gen_mac_addr_t)(const unsigned char *mac_addr, unsigned
* @brief free the message after finish DH
*
*/
-typedef void * (*esp_dh5_free_t)(void *ctx);
+typedef void (*esp_dh5_free_t)(void *ctx);
/**
* @brief Build WPS IE for (Re)Association Request
@@ -697,6 +699,8 @@ typedef int (*esp_wps_is_selected_pbc_registrar_t)(const void *msg, unsigned cha
* hardware.
*/
typedef struct {
+ uint32_t size;
+ uint32_t version;
esp_aes_wrap_t aes_wrap; /**< station connect function used when send EAPOL frame */
esp_aes_unwrap_t aes_unwrap; /**< station connect function used when decrypt key data */
esp_hmac_sha256_vector_t hmac_sha256_vector; /**< station connect function used when check MIC */
@@ -724,6 +728,8 @@ typedef struct {
* hardware.
*/
typedef struct{
+ uint32_t size;
+ uint32_t version;
esp_aes_128_encrypt_t aes_128_encrypt; /**< function used to process message when do WPS */
esp_aes_128_decrypt_t aes_128_decrypt; /**< function used to process message when do WPS */
esp_crypto_mod_exp_t crypto_mod_exp; /**< function used to calculate public key and private key */
@@ -750,6 +756,8 @@ typedef struct{
* hardware.
*/
typedef struct {
+ uint32_t size;
+ uint32_t version;
esp_crypto_hash_init_t crypto_hash_init; /**< function used to initialize a crypto_hash structure when use TLSV1 */
esp_crypto_hash_update_t crypto_hash_update; /**< function used to calculate hash data when use TLSV1 */
esp_crypto_hash_finish_t crypto_hash_finish; /**< function used to finish the hash calculate when use TLSV1 */
@@ -765,6 +773,8 @@ typedef struct {
esp_eap_peer_blob_deinit_t eap_peer_blob_deinit;
esp_eap_peer_config_init_t eap_peer_config_init;
esp_eap_peer_config_deinit_t eap_peer_config_deinit;
+ esp_eap_peer_register_methods_t eap_peer_register_methods;
+ esp_eap_peer_unregister_methods_t eap_peer_unregister_methods;
esp_eap_deinit_prev_method_t eap_deinit_prev_method;
esp_eap_peer_get_eap_method_t eap_peer_get_eap_method;
esp_eap_sm_abort_t eap_sm_abort;
diff --git a/components/esp32/include/esp_wifi_internal.h b/components/esp32/include/esp_wifi_internal.h
index 875e5ac04a..f486b7aaf6 100644
--- a/components/esp32/include/esp_wifi_internal.h
+++ b/components/esp32/include/esp_wifi_internal.h
@@ -127,6 +127,26 @@ esp_err_t esp_wifi_internal_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn);
*/
esp_err_t esp_wifi_internal_set_sta_ip(void);
+/**
+ * @brief enable or disable transmitting WiFi MAC frame with fixed rate
+ *
+ * @attention 1. If fixed rate is enabled, both management and data frame are transmitted with fixed rate
+ * @attention 2. Make sure that the receiver is able to receive the frame with the fixed rate if you want the frame to be received
+ *
+ * @param ifx : wifi interface
+ * @param en : false - disable, true - enable
+ * @param rate : PHY rate
+ *
+ * @return
+ * - ERR_OK : succeed
+ * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
+ * - ESP_ERR_WIFI_NOT_STARTED: WiFi was not started by esp_wifi_start
+ * - ESP_ERR_WIFI_IF : invalid WiFi interface
+ * - ESP_ERR_INVALID_ARG : invalid rate
+ * - ESP_ERR_NOT_SUPPORTED : do not support to set fixed rate if TX AMPDU is enabled
+ */
+esp_err_t esp_wifi_internal_set_fix_rate(wifi_interface_t ifx, bool en, wifi_phy_rate_t rate);
+
/**
* @brief Check the MD5 values of the OS adapter header files in IDF and WiFi library
*
@@ -138,6 +158,28 @@ esp_err_t esp_wifi_internal_set_sta_ip(void);
*/
esp_err_t esp_wifi_internal_osi_funcs_md5_check(const char *md5);
+/**
+ * @brief Check the MD5 values of the crypto types header files in IDF and WiFi library
+ *
+ * @attention 1. It is used for internal CI version check
+ *
+ * @return
+ * - ESP_OK : succeed
+ * - ESP_WIFI_INVALID_ARG : MD5 check fail
+ */
+esp_err_t esp_wifi_internal_crypto_funcs_md5_check(const char *md5);
+
+/**
+ * @brief Check the git commit id of WiFi library
+ *
+ * @attention 1. It is used for internal CI WiFi library check
+ *
+ * @return
+ * - ESP_OK : succeed
+ * - ESP_FAIL : fail
+ */
+esp_err_t esp_wifi_internal_git_commit_id_check(void);
+
/**
* @brief Allocate a chunk of memory for WiFi driver
*
diff --git a/components/esp32/include/esp_wifi_types.h b/components/esp32/include/esp_wifi_types.h
index 97757f0b8a..8d331155d3 100644
--- a/components/esp32/include/esp_wifi_types.h
+++ b/components/esp32/include/esp_wifi_types.h
@@ -97,8 +97,8 @@ typedef enum {
typedef enum {
WIFI_SECOND_CHAN_NONE = 0, /**< the channel width is HT20 */
- WIFI_SECOND_CHAN_ABOVE, /**< the channel width is HT40 and the second channel is above the primary channel */
- WIFI_SECOND_CHAN_BELOW, /**< the channel width is HT40 and the second channel is below the primary channel */
+ WIFI_SECOND_CHAN_ABOVE, /**< the channel width is HT40 and the secondary channel is above the primary channel */
+ WIFI_SECOND_CHAN_BELOW, /**< the channel width is HT40 and the secondary channel is below the primary channel */
} wifi_second_chan_t;
typedef enum {
@@ -155,7 +155,7 @@ typedef struct {
uint8_t bssid[6]; /**< MAC address of AP */
uint8_t ssid[33]; /**< SSID of AP */
uint8_t primary; /**< channel of AP */
- wifi_second_chan_t second; /**< second channel of AP */
+ wifi_second_chan_t second; /**< secondary channel of AP */
int8_t rssi; /**< signal strength of AP */
wifi_auth_mode_t authmode; /**< authmode of AP */
wifi_cipher_type_t pairwise_cipher; /**< pairwise cipher of AP */
@@ -186,6 +186,8 @@ typedef struct {
wifi_auth_mode_t authmode; /**< The weakest authmode to accept in the fast scan mode */
}wifi_fast_scan_threshold_t;
+typedef wifi_fast_scan_threshold_t wifi_scan_threshold_t; /**< wifi_fast_scan_threshold_t only used in fast scan mode once, now it enabled in all channel scan, the wifi_fast_scan_threshold_t will be remove in version 4.0 */
+
typedef enum {
WIFI_PS_NONE, /**< No power save */
WIFI_PS_MIN_MODEM, /**< Minimum modem power saving. In this mode, station wakes up to receive beacon every DTIM period */
@@ -226,7 +228,7 @@ typedef struct {
uint8_t channel; /**< channel of target AP. Set to 1~13 to scan starting from the specified channel before connecting to AP. If the channel of AP is unknown, set it to 0.*/
uint16_t listen_interval; /**< Listen interval for ESP32 station to receive beacon when WIFI_PS_MAX_MODEM is set. Units: AP beacon intervals. Defaults to 3 if set to 0. */
wifi_sort_method_t sort_method; /**< sort the connect AP in the list by rssi or security mode */
- wifi_fast_scan_threshold_t threshold; /**< When scan_method is set to WIFI_FAST_SCAN, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. */
+ wifi_scan_threshold_t threshold; /**< When scan_method is set, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. */
} wifi_sta_config_t;
/** @brief Configuration data for ESP32 AP or STA.
@@ -304,33 +306,33 @@ typedef struct {
/** @brief Received packet radio metadata header, this is the common header at the beginning of all promiscuous mode RX callback buffers */
typedef struct {
- signed rssi:8; /**< signal intensity of packet */
- unsigned rate:5; /**< data rate */
- unsigned :1; /**< reserve */
- unsigned sig_mode:2; /**< 0:is not 11n packet; 1:is 11n packet */
- unsigned :16; /**< reserve */
- unsigned mcs:7; /**< if is 11n packet, shows the modulation(range from 0 to 76) */
- unsigned cwb:1; /**< if is 11n packet, shows if is HT40 packet or not */
- unsigned :16; /**< reserve */
- unsigned smoothing:1; /**< reserve */
- unsigned not_sounding:1; /**< reserve */
- unsigned :1; /**< reserve */
- unsigned aggregation:1; /**< Aggregation */
- unsigned stbc:2; /**< STBC */
- unsigned fec_coding:1; /**< Flag is set for 11n packets which are LDPC */
- unsigned sgi:1; /**< SGI */
- signed noise_floor:8; /**< noise floor */
- unsigned ampdu_cnt:8; /**< ampdu cnt */
- unsigned channel:4; /**< which primary channel this packet in */
- unsigned second_channel:4;/**< which second channel this packet in */
- unsigned :8; /**< reserve */
- unsigned timestamp:32; /**< timestamp, unit: microsecond */
- unsigned :32; /**< reserve */
- unsigned :31; /**< reserve */
- unsigned ant:1; /**< antenna number from which this packet is received */
- unsigned sig_len:12; /**< length of packet */
- unsigned :12; /**< reserve */
- unsigned rx_state:8; /**< rx state */
+ signed rssi:8; /**< Received Signal Strength Indicator(RSSI) of packet. unit: dBm */
+ unsigned rate:5; /**< PHY rate encoding of the packet. Only valid for non HT(11bg) packet */
+ unsigned :1; /**< reserve */
+ unsigned sig_mode:2; /**< 0: non HT(11bg) packet; 1: HT(11n) packet; 3: VHT(11ac) packet */
+ unsigned :16; /**< reserve */
+ unsigned mcs:7; /**< Modulation Coding Scheme. If is HT(11n) packet, shows the modulation, range from 0 to 76(MSC0 ~ MCS76) */
+ unsigned cwb:1; /**< Channel Bandwidth of the packet. 0: 20MHz; 1: 40MHz */
+ unsigned :16; /**< reserve */
+ unsigned smoothing:1; /**< reserve */
+ unsigned not_sounding:1; /**< reserve */
+ unsigned :1; /**< reserve */
+ unsigned aggregation:1; /**< Aggregation. 0: MPDU packet; 1: AMPDU packet */
+ unsigned stbc:2; /**< Space Time Block Code(STBC). 0: non STBC packet; 1: STBC packet */
+ unsigned fec_coding:1; /**< Flag is set for 11n packets which are LDPC */
+ unsigned sgi:1; /**< Short Guide Interval(SGI). 0: Long GI; 1: Short GI */
+ signed noise_floor:8; /**< noise floor of Radio Frequency Module(RF). unit: 0.25dBm*/
+ unsigned ampdu_cnt:8; /**< ampdu cnt */
+ unsigned channel:4; /**< primary channel on which this packet is received */
+ unsigned secondary_channel:4; /**< secondary channel on which this packet is received. 0: none; 1: above; 2: below */
+ unsigned :8; /**< reserve */
+ unsigned timestamp:32; /**< timestamp. The local time when this packet is received. It is precise only if modem sleep or light sleep is not enabled. unit: microsecond */
+ unsigned :32; /**< reserve */
+ unsigned :31; /**< reserve */
+ unsigned ant:1; /**< antenna number from which this packet is received. 0: WiFi antenna 0; 1: WiFi antenna 1 */
+ unsigned sig_len:12; /**< length of packet including Frame Check Sequence(FCS) */
+ unsigned :12; /**< reserve */
+ unsigned rx_state:8; /**< state of the packet. 0: no error; others: error numbers which are not public */
} wifi_pkt_rx_ctrl_t;
/** @brief Payload passed to 'buf' parameter of promiscuous mode RX callback.
@@ -387,10 +389,10 @@ typedef struct {
*
*/
typedef struct {
- bool lltf_en; /**< enable to receive legacy long training field(lltf) data */
- bool htltf_en; /**< enable to receive HT long training field(htltf) data */
- bool stbcltf2_en; /**< enable to receive space time block code long training field(stbcltf2) data */
- bool manu_scale; /**< manually scale the CSI data by left shifting or automatically scale the CSI data. If set true, please set the shift bits. false: automatically. true: manually */
+ bool lltf_en; /**< enable to receive legacy long training field(lltf) data. Default enabled */
+ bool htltf_en; /**< enable to receive HT long training field(htltf) data. Default enabled */
+ bool stbc_htltf2_en; /**< enable to receive space time block code HT long training field(stbc-htltf2) data. Default enabled */
+ bool manu_scale; /**< manually scale the CSI data by left shifting or automatically scale the CSI data. If set true, please set the shift bits. false: automatically. true: manually. Default false */
uint8_t shift; /**< manually left shift bits of the scale of the CSI data. The range of the left shift bits is 0~15 */
} wifi_csi_config_t;
@@ -402,7 +404,7 @@ typedef struct {
wifi_pkt_rx_ctrl_t rx_ctrl;/**< received packet radio metadata header of the CSI data */
uint8_t mac[6]; /**< source MAC address of the CSI data */
bool last_word_invalid; /**< last four bytes of the CSI data is invalid or not */
- uint8_t *buf; /**< buffer of CSI data */
+ int8_t *buf; /**< buffer of CSI data */
uint16_t len; /**< length of CSI data */
} wifi_csi_info_t;
@@ -446,6 +448,47 @@ typedef struct {
enabled_ant1: 4; /**< Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT1 */
} wifi_ant_config_t;
+/**
+ * @brief WiFi PHY rate encodings
+ *
+ */
+typedef enum {
+ WIFI_PHY_RATE_1M_L = 0x00, /**< 1 Mbps with long preamble */
+ WIFI_PHY_RATE_2M_L = 0x01, /**< 2 Mbps with long preamble */
+ WIFI_PHY_RATE_5M_L = 0x02, /**< 5.5 Mbps with long preamble */
+ WIFI_PHY_RATE_11M_L = 0x03, /**< 11 Mbps with long preamble */
+ WIFI_PHY_RATE_2M_S = 0x05, /**< 2 Mbps with short preamble */
+ WIFI_PHY_RATE_5M_S = 0x06, /**< 5.5 Mbps with short preamble */
+ WIFI_PHY_RATE_11M_S = 0x07, /**< 11 Mbps with short preamble */
+ WIFI_PHY_RATE_48M = 0x08, /**< 48 Mbps */
+ WIFI_PHY_RATE_24M = 0x09, /**< 24 Mbps */
+ WIFI_PHY_RATE_12M = 0x0A, /**< 12 Mbps */
+ WIFI_PHY_RATE_6M = 0x0B, /**< 6 Mbps */
+ WIFI_PHY_RATE_54M = 0x0C, /**< 54 Mbps */
+ WIFI_PHY_RATE_36M = 0x0D, /**< 36 Mbps */
+ WIFI_PHY_RATE_18M = 0x0E, /**< 18 Mbps */
+ WIFI_PHY_RATE_9M = 0x0F, /**< 9 Mbps */
+ WIFI_PHY_RATE_MCS0_LGI = 0x10, /**< MCS0 with long GI, 6.5 Mbps for 20MHz, 13.5 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS1_LGI = 0x11, /**< MCS1 with long GI, 13 Mbps for 20MHz, 27 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS2_LGI = 0x12, /**< MCS2 with long GI, 19.5 Mbps for 20MHz, 40.5 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS3_LGI = 0x13, /**< MCS3 with long GI, 26 Mbps for 20MHz, 54 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS4_LGI = 0x14, /**< MCS4 with long GI, 39 Mbps for 20MHz, 81 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS5_LGI = 0x15, /**< MCS5 with long GI, 52 Mbps for 20MHz, 108 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS6_LGI = 0x16, /**< MCS6 with long GI, 58.5 Mbps for 20MHz, 121.5 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS7_LGI = 0x17, /**< MCS7 with long GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS0_SGI = 0x18, /**< MCS0 with short GI, 7.2 Mbps for 20MHz, 15 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS1_SGI = 0x19, /**< MCS1 with short GI, 14.4 Mbps for 20MHz, 30 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS2_SGI = 0x1A, /**< MCS2 with short GI, 21.7 Mbps for 20MHz, 45 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS3_SGI = 0x1B, /**< MCS3 with short GI, 28.9 Mbps for 20MHz, 60 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS4_SGI = 0x1C, /**< MCS4 with short GI, 43.3 Mbps for 20MHz, 90 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS5_SGI = 0x1D, /**< MCS5 with short GI, 57.8 Mbps for 20MHz, 120 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS6_SGI = 0x1E, /**< MCS6 with short GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz */
+ WIFI_PHY_RATE_MCS7_SGI = 0x1F, /**< MCS7 with short GI, 72.2 Mbps for 20MHz, 150 Mbps for 40MHz */
+ WIFI_PHY_RATE_LORA_250K = 0x29, /**< 250 Kbps */
+ WIFI_PHY_RATE_LORA_500K = 0x2A, /**< 500 Kbps */
+ WIFI_PHY_RATE_MAX,
+} wifi_phy_rate_t;
+
#ifdef __cplusplus
}
#endif
diff --git a/components/esp32/include/rom/gpio.h b/components/esp32/include/rom/gpio.h
index a760d1a3d7..f98d6cf2dd 100644
--- a/components/esp32/include/rom/gpio.h
+++ b/components/esp32/include/rom/gpio.h
@@ -20,6 +20,7 @@
#include "esp_attr.h"
#include "soc/gpio_reg.h"
+#include "soc/gpio_pins.h"
#ifdef __cplusplus
extern "C" {
@@ -35,7 +36,6 @@ extern "C" {
#define GPIO_REG_READ(reg) READ_PERI_REG(reg)
#define GPIO_REG_WRITE(reg, val) WRITE_PERI_REG(reg, val)
-#define GPIO_PIN_COUNT 40
#define GPIO_ID_PIN0 0
#define GPIO_ID_PIN(n) (GPIO_ID_PIN0+(n))
#define GPIO_PIN_ADDR(i) (GPIO_PIN0_REG + i*4)
diff --git a/components/esp32/include/rom/libc_stubs.h b/components/esp32/include/rom/libc_stubs.h
index 0c1876e585..90c0b44688 100644
--- a/components/esp32/include/rom/libc_stubs.h
+++ b/components/esp32/include/rom/libc_stubs.h
@@ -51,7 +51,7 @@ struct syscall_stub_table
int (*_rename_r)(struct _reent *r, const char*, const char*);
clock_t (*_times_r)(struct _reent *r, struct tms *);
int (*_gettimeofday_r) (struct _reent *r, struct timeval *, void *);
- void (*_raise_r)(struct _reent *r);
+ void (*_raise_r)(struct _reent *r); /* function signature is incorrect in ROM */
int (*_unlink_r)(struct _reent *r, const char*);
int (*_link_r)(struct _reent *r, const char*, const char*);
int (*_stat_r)(struct _reent *r, const char*, struct stat *);
diff --git a/components/esp32/include/rom/rtc.h b/components/esp32/include/rom/rtc.h
index 3161fb2748..08d8ace094 100644
--- a/components/esp32/include/rom/rtc.h
+++ b/components/esp32/include/rom/rtc.h
@@ -192,7 +192,7 @@ void set_rtc_memory_crc(void);
*
* @return None
*/
-void software_reset(void);
+void __attribute__((noreturn)) software_reset(void);
/**
* @brief Software Reset digital core.
diff --git a/components/esp32/include/xtensa/board.h b/components/esp32/include/xtensa/board.h
deleted file mode 100644
index c6b04a2505..0000000000
--- a/components/esp32/include/xtensa/board.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* This header is supposed to be obtained from /xtensa/board.h
- using a -I directive passed to the compiler. */
-
-#error "Unspecified board. Missing -I directive to select supported Xtensa board, usually -I XTENSA_TOOLS_ROOT/xtensa-elf/include/xtensa/ (XTENSA_TOOLS_ROOT is root of Xtensa Tools install, see xt-run --show-config=xttools)"
-
-/*
- * Copyright (c) 2013 Tensilica Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
diff --git a/components/esp32/include/xtensa/c6x-compat.h b/components/esp32/include/xtensa/c6x-compat.h
deleted file mode 100644
index 4b17987ea9..0000000000
--- a/components/esp32/include/xtensa/c6x-compat.h
+++ /dev/null
@@ -1,1758 +0,0 @@
-/*
- * Copyright (c) 2006-2010 Tensilica Inc. ALL RIGHTS RESERVED.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef __C6X_COMPAT__H
-#define __C6X_COMPAT__H
-
-/* Unimplemented functions _gmpy, _gmpy4, _xormpy, _lssub, _cmpy, _cmpyr,
- _cmpyr1, _ddotpl2r, _ddotph2r */
-
-
-typedef long long C6X_COMPAT_LONG40;
-
-
-#define _memd8(a) (*((double*)(a)))
-#define _memd8_const(a) (*((const double*)(a)))
-
-#define _amemd8(a) (*((double*)(a)))
-#define _amemd8_const(a) (*((const double*)(a)))
-
-#define _mem8(a) (*((unsigned long long*)(a)))
-#define _mem8_const(a) (*((const unsigned long long*)(a)))
-
-#define _mem4(a) (*((unsigned*)(a)))
-#define _mem4_const(a) (*((const unsigned*)(a)))
-#define _amem4_const(a) (*((const unsigned*)(a)))
-
-/* NOTE: To emulate a C6X properly you should define global variables
- for your Xtensa with these names. Some of the emulation routines
- will set these values. */
-
-extern int _carry;
-extern int _overflow;
-
-// Utility routines
-
-
-#define TESTBIT(x,n) (((x) >> (n)) & 1)
-
-#define NSA_BITS 32
-
-static inline unsigned int norm_shift_amt_U_and_non_U(int is_signed, int inp) {
-int j=0, k=0;
-int x=inp;
-if (is_signed) {
- /* Invert signed val if negative */
- x= TESTBIT(x,(NSA_BITS-1))? ~x: x;
- x= (x&1)|(x<<1); /* Shift up to return count-1 */
- if (x ==0)
- return NSA_BITS-1;
- }
- if (x ==0)
- return NSA_BITS;
- /* Now count leading zeros */
- for (j=0, k=NSA_BITS-1; k>=0; j++, k--) {
- if (TESTBIT(x,k))
- return j;
- }
- return NSA_BITS;
-}
-
-
-
-static inline long long
-orig_L40_set( long long L40_var1) {
- long long L40_var_out;
-
- L40_var_out = L40_var1 & 0x000000ffffffffffLL;
-
- if( L40_var1 & 0x8000000000LL)
- L40_var_out = L40_var_out | 0xffffff0000000000LL;
-
- return( L40_var_out);
-}
-
-
-
-static inline signed long long
-util_saturate_n_no_state(signed long long t, int n)
-{
- signed long long maxv, minv;
- maxv = (1LL << (n-1)) - 1;
- minv = (-1LL << (n-1));
- if (t > maxv) {
- t = maxv;
- } else if (t < minv) {
- t = minv;
- }
- return t;
-}
-
-
-static inline signed long long
-util_saturate_n_sgn(signed long long t, int n)
-{
- signed long long result;
- signed long long maxv, minv;
- maxv = (1LL << (n-1)) - 1;
- minv = (-1LL << (n-1));
- if (t > 0) {
- result = maxv;
- _overflow = 1;
- } else if (t < 0) {
- result = minv;
- _overflow = 1;
- } else {
- result = 0;
- }
- return result;
-}
-
-
-
-
-/* well-behaved signed shift right (left on negative) with
- saturation */
-static inline signed long long
-util_shift_right_saturate_n(signed long long t, int shval, int n)
-{
- /* n should be <= 62 */
- long long result;
-
- signed long long mask;
- int actual_shift = shval;
- long long shft = actual_shift > 0 ? actual_shift : -actual_shift;
-
- if (t == 0 || actual_shift == 0)
- return t;
-
- if (actual_shift >= n) {
- return (t < 0) ? -1 : 0;
- }
- if (actual_shift <= -n) {
- return util_saturate_n_sgn(t, n);
- }
- if (actual_shift > 0) {
- return t >> actual_shift;
- }
- /* actual_shift < 0. Check for saturation after shift. */
- mask = (-1LL << (n-shft-1));
- if (t > 0 && ((mask & t) != 0)) {
- return util_saturate_n_sgn(t, n);
- }
- if (t < 0 && ((mask & t) != mask)) {
- return util_saturate_n_sgn(t, n);
- }
- result = t << shft;
-
- return result;
-}
-
-
-/* Implemented c6x standard C compatibility functions (alphabetical
- order) */
-
-
-static inline int _abs(int src1) {
- if ((unsigned) src1 == (unsigned) 0x80000000) {
- return 0x7fffffff;
- }
- return abs(src1);
-}
-
-
-static inline int _abs2(int src1) {
- short s1[2],r[2];
- int result;
- *((int*)s1) = src1;
- if ((unsigned short) s1[1] == (unsigned short) 0x8000) r[1] = 0x7fff;
- else r[1] = abs(s1[1]);
- if ((unsigned short) s1[0] == (unsigned short) 0x8000) r[0] = 0x7fff;
- else r[0] = abs(s1[0]);
- result = *(int*)r;
- return result;
- }
-
-
-
-
-static inline int _add2(int src1, int src2) {
- short s1[2], s2[2], r[2];
- int result;
- *((int*)s1) = src1;
- *((int*)s2) = src2;
- r[0] = s1[0] + s2[0];
- r[1] = s1[1] + s2[1];
- result = *(int*)r;
- return result;
-}
-
-static inline int _add4(int src1, int src2) {
- char c1[4], c2[4], r[4];
- int result;
- *((int*)c1) = src1;
- *((int*)c2) = src2;
- r[0] = c1[0] + c2[0];
- r[1] = c1[1] + c2[1];
- r[2] = c1[2] + c2[2];
- r[3] = c1[3] + c2[3];
- result = *(int*)r;
- return result;
-}
-
-
-
-static inline long long _addsub(unsigned int src1, unsigned int src2)
-{
-
- int res_lo;
- int res_hi;
-
- res_hi = src1+src2;
- res_lo = src1-src2;
- return (((unsigned long long) res_hi) << 32) | ((unsigned int) res_lo) ;
-}
-
-
-static inline long long _addsub2(unsigned int src1, unsigned int src2)
-{
- short s1[2], s2[2], ra[2], rs[2];
- int res_lo;
- int res_hi;
-
- *((int*)s1) = src1;
- *((int*)s2) = src2;
- ra[0] = s1[0] + s2[0];
- ra[1] = s1[1] + s2[1];
- rs[0] = s1[0] - s2[0];
- rs[1] = s1[1] - s2[1];
-
- res_hi = *(int*)ra;
- res_lo = *(int*)rs;
- return (((unsigned long long) res_hi) << 32) | ((unsigned int) res_lo) ;
-}
-
-
-static inline int _avg2(int src1, int src2) {
- int low = (((int)1 + (short) src1 + (short) src2) >> 1) & 0XFFFF;
- int high1 = src1 >> 16;
- int high2 = src2 >> 16;
- int high = ((high1 + high2 + 1) >> 1)<< 16;
- return high | low;
-}
-
-
-
-static inline unsigned int _avgu4(unsigned int src1, unsigned int src2) {
-unsigned int res0 = ((src1 & 0xFF) + (src2 & 0xFF) + 1) >> 1;
- unsigned int res1 = (((src1 & 0xFF00) >> 8) + ((src2 & 0xFF00) >> 8) + 1) >> 1;
- unsigned int res2 = (((src1 & 0xFF0000) >> 16) + ((src2 & 0xFF0000) >> 16) + 1) >> 1;
- unsigned int res3 = (((src1 & 0xFF000000) >> 24) + ((src2 & 0xFF000000) >> 24) + 1) >> 1;
- return (res3 << 24) | (res2 << 16) | (res1 << 8) | res0;
-}
-
-
-static inline int TEN_popc (unsigned char b)
-{
- int i, result = 0;
- for (i = 0; i < 8; i++){
- if (b & 0x1)
- result++;
- b >>= 1;
- }
- return result;
-}
-
-static inline unsigned int _bitc4(unsigned int src1)
-{
- unsigned int res0 = TEN_popc(src1 & 0xFF);
- unsigned int res1 = TEN_popc((src1 & 0xFF00) >> 8);
- unsigned int res2 = TEN_popc((src1 & 0xFF0000) >> 16);
- unsigned int res3 = TEN_popc((src1 & 0xFF000000) >> 24);
- return (res3 << 24) | (res2 << 16) | (res1 << 8) | res0;
-}
-
-static inline unsigned int _bitr(unsigned int src) {
- int i;
- unsigned r = 0;
- for (i = 0; i< 32; ++i) {
- r = r | (((src >> i) & 1)<<(31-i));
- }
- return r;
-}
-
-
-static inline unsigned int _clr(unsigned int src2, int csta, int cstb)
-{
- csta &= 0x1f;
- cstb &= 0x1f;
- if (csta > cstb)
- return src2;
- else {
- unsigned int mask = (((1 << (cstb - csta)) << 1) - 1) << csta;
- return src2 & (~mask);
- }
-}
-
-static inline unsigned int _clrr(unsigned int src2, int src1)
-{
- unsigned int csta = (src1 >> 5) & 0x1f;
- unsigned int cstb = src1 & 0x1f;
- if (csta > cstb)
- return src2;
- else {
- unsigned int mask = (((1 << (cstb - csta)) << 1) - 1) << csta;
- return src2 & (~mask);
- }
-}
-
-
-
-
-static inline int _cmpeq2(int src1, int src2) {
- short s1[2], s2[2];
- int r0, r1;
- int result;
- *((int*)s1) = src1;
- *((int*)s2) = src2;
- r0 = s1[0] == s2[0] ? 1 : 0;
- r1 = s1[1] == s2[1] ? 1 : 0;
- result = (r1 << 1) | r0;
- return result;
-}
-
-static inline int _cmpeq4(int src1, int src2) {
- char s1[4], s2[4];
- int r0, r1, r2, r3;
- int result;
- *((int*)s1) = src1;
- *((int*)s2) = src2;
- r0 = s1[0] == s2[0] ? 1 : 0;
- r1 = s1[1] == s2[1] ? 1 : 0;
- r2 = s1[2] == s2[2] ? 1 : 0;
- r3 = s1[3] == s2[3] ? 1 : 0;
- result = (r3 << 3) | (r2 << 2) | (r1 << 1) | r0;
- return result;
-}
-
-
-static inline int _cmpgt2(int src1, int src2) {
- short s1[2], s2[2];
- int r1, r0;
- int result;
- *((int*)s1) = src1;
- *((int*)s2) = src2;
- r0 = s1[0] > s2[0] ? 1 : 0;
- r1 = s1[1] > s2[1] ? 1 : 0;
- result = (r1<<1) | r0;
- return result;
-}
-
-
-static inline unsigned int _cmpgtu4(unsigned int src1, unsigned int src2) {
- unsigned int s1_0 = (src1 & 0xFF);
- unsigned int s1_1 = (src1 & 0xFF00) >> 8;
- unsigned int s1_2 = (src1 & 0xFF0000) >> 16;
- unsigned int s1_3 = (src1 & 0xFF000000) >> 24;
-
- unsigned int s2_0 = (src2 & 0xFF);
- unsigned int s2_1 = (src2 & 0xFF00) >> 8;
- unsigned int s2_2 = (src2 & 0xFF0000) >> 16;
- unsigned int s2_3 = (src2 & 0xFF000000) >> 24;
-
- unsigned int result = 0;
-
- if (s1_0 > s2_0)
- result |= 0x1;
-
- if (s1_1 > s2_1)
- result |= 0x2;
-
- if (s1_2 > s2_2)
- result |= 0x4;
-
- if (s1_3 > s2_3)
- result |= 0x8;
-
- return result;
-}
-
-
-
-
-static inline long long _ddotp4(unsigned int src1, unsigned int src2) {
- unsigned int res0, res1;
- short s1_0 = (src1 & 0xffff);
- short s1_1 = (src1 & 0xfff0000) >> 16;
-
- unsigned short s2_0 = (src2 & 0xff);
- unsigned short s2_1 = (src2 & 0xff00) >> 8;
- unsigned short s2_2 = (src2 & 0xff0000) >> 16;
- unsigned short s2_3 = (src2 & 0xff000000) >> 24;
-
- res0 = ((int)s1_0) * s2_0 + ((int)s1_1) * s2_1;
- res1 = ((int)s1_0) * s2_2 + ((int)s1_1) * s2_3;
-
- return (res1 << 16) | res0;
-}
-
-
-static inline long long _ddotph2(long long src1_o_src1_e, unsigned int src2)
-{
-
- unsigned int src1_o = src1_o_src1_e >> 32;
- unsigned int src1_e = src1_o_src1_e & 0xFFFFFFFF;
- short ls1_o = src1_o & 0XFFFF;
- short hs1_o = src1_o >> 16;
-// short ls1_e = src1_e & 0XFFFF;
- short hs1_e = src1_e >> 16;
- short ls2 = src2 & 0XFFFF;
- short hs2 = src2 >> 16;
-
- unsigned long long res_hi = ls2 * ls1_o + hs2 * hs1_o;
- unsigned int res_lo = ls1_o * hs2 + hs1_e * ls2;
- return (res_hi << 32) | res_lo;
-}
-
-
-static inline long long _ddotpl2(long long src1_o_src1_e, unsigned int src2)
-{
- unsigned int src1_o = src1_o_src1_e >> 32;
- unsigned int src1_e = src1_o_src1_e & 0xFFFFFFFF;
- short ls1_o = src1_o & 0XFFFF;
-// short hs1_o = src1_o >> 16;
- short ls1_e = src1_e & 0XFFFF;
- short hs1_e = src1_e >> 16;
- short ls2 = src2 & 0XFFFF;
- short hs2 = src2 >> 16;
-
- unsigned long long res_hi = ls2 * hs1_e + hs2 * ls1_o;
- unsigned res_lo = hs1_e * hs2 + ls1_e * ls2;
- return (res_hi << 32) | res_lo;
-}
-
-
-static inline unsigned int _deal(unsigned int src)
-{
- int i;
- unsigned short lo = 0, hi = 0;
- for (i = 0; i < 32; i+= 2) {
- lo >>= 1;
- lo |= (src & 0x1) << 15;
- src >>= 1;
- hi >>= 1;
- hi |= (src & 0x1) << 15;
- src >>= 1;
- }
- return (hi << 16) | lo;
-}
-
-
-static inline long long _dmv(unsigned int src1, unsigned int src2)
-{
- return (((long long) src1) << 32) | src2;
-}
-
-
-static inline int _dotpn2(int src1, int src2) {
-short int s1_h = src1>>16;
- short int s1_l = src1;
- short int s2_h = src2>>16;
- short int s2_l = src2;
- return s1_h * s2_h - s1_l * s2_l;
-}
-
-
-static inline int _dotp2(int src1, int src2) {
- short int s1_h = src1>>16;
- short int s1_l = src1;
- short int s2_h = src2>>16;
- short int s2_l = src2;
- return s1_h * s2_h + s1_l * s2_l;
-}
-
-
-
-static inline int _dotpnrsu2(int src1, unsigned int src2)
-{
- short ls1 = src1 & 0XFFFF;
- unsigned short ls2 = src2 & 0XFFFF;
- short hs1 = src1 >> 16;
- unsigned short hs2 = src2 >> 16;
-
- int result = (((long long) (int)(hs1 * hs2)) - ((long long) (int)(ls1 * ls2)) + (1 << 15)) >> 16;
- return result;
-}
-
-
-
-static inline int _dotprsu2(int src1, unsigned int src2) {
- short ls1 = src1 & 0XFFFF;
- unsigned short ls2 = (src2 & 0XFFFF);
- short hs1 = src1 >> 16;
- unsigned short hs2 = (src2 >> 16);
-
- int result = (((long long) (int) (ls1 * ls2)) + ((long long) (int) (hs1 * hs2)) + (1LL << 15)) >> 16;
- return result;
-}
-
-
-
-
-
-
-
-static inline int _dotpsu4(int src1, unsigned int src2) {
- int result;
- signed char s1_0 = (src1 & 0xff);
- signed char s1_1 = (src1 & 0xff00) >> 8;
- signed char s1_2 = (src1 & 0xff0000) >> 16;
- signed char s1_3 = (src1 & 0xff000000) >> 24;
-
- unsigned int s2_0 = (src2 & 0xff);
- unsigned int s2_1 = (src2 & 0xff00) >> 8;
- unsigned int s2_2 = (src2 & 0xff0000) >> 16;
- unsigned int s2_3 = (src2 & 0xff000000) >> 24;
-
- result = s1_0 * s2_0 + s1_1 * s2_1 + s1_2 * s2_2 + s1_3 * s2_3;
- return result;
-}
-
-
-static inline unsigned int _dotpu4(unsigned int src1, unsigned int src2) {
- unsigned char v1_0 = src1 & 0xff;
- unsigned char v1_1 = (src1>>8) & 0xff;
- unsigned char v1_2 = (src1>>16) & 0xff;
- unsigned char v1_3 = (src1>>24) & 0xff;
-
- unsigned char v2_0 = src2 & 0xff;
- unsigned char v2_1 = (src2>>8) & 0xff;
- unsigned char v2_2 = (src2>>16) & 0xff;
- unsigned char v2_3 = (src2>>24) & 0xff;
-
- unsigned v = v1_0 * v2_0 + v1_1 * v2_1 + v1_2 * v2_2 + v1_3 * v2_3;
- return v;
-}
-
-
-static inline long long _dpack2(unsigned int src1, unsigned int src2){
-unsigned short s1[2], s2[2];
-*((int*)s1) = src1;
-*((int*)s2) = src2;
-return ((unsigned long long) s1[1] << 48) | ((unsigned long long) s2[1] << 32) | ((unsigned long long) s1[0] << 16) | ((unsigned long long) s2[0]);
-}
-
-
-static inline long long _dpackx2(unsigned int src1, unsigned int src2){
-unsigned short s1[2], s2[2];
-*((int*)s1) = src1;
-*((int*)s2) = src2;
-return ((unsigned long long) s2[0] << 48) | ((unsigned long long) s1[1] << 32) | ((unsigned long long) s1[0] << 16) | ((unsigned long long) s2[1]);
-}
-
-static inline int _ext(int src2, unsigned int csta, unsigned int cstb)
-{
- return (src2 << csta) >> cstb;
-}
-
-static inline int _extr(int src2, int src1)
-{
- unsigned int csta = (src1 >> 5) & 0x1f;
- unsigned int cstb = src1 & 0x1f;
- return (src2 << csta) >> cstb;
-}
-
-static inline unsigned int _extu(unsigned int src2, unsigned int csta, unsigned int cstb)
-{
- return (src2 << csta) >> cstb;
-}
-
-static inline unsigned int _extur(unsigned int src2, int src1)
-{
- unsigned int csta = (src1 >> 5) & 0x1f;
- unsigned int cstb = src1 & 0x1f;
- return (src2 << csta) >> cstb;
-}
-
-
-static inline unsigned long long _hi(double src) {
- unsigned long long v;
- *(double*)&v = src;
- return v>>32;
-}
-
-static inline unsigned int _hill (long long src)
-{
- return (unsigned int) (src >> 32);
-}
-
-
-
-static inline double _itod(unsigned hi, unsigned lo) {
- double v;
- unsigned long long ll = ((((unsigned long long)(hi))<<32) | (unsigned long long)((unsigned)lo));
- *((unsigned long long *)&v) = ll;
- return v;
-}
-
-
-static inline long long _itoll(unsigned int src2, unsigned int src1)
-{
- return (((long long) src2) << 32) | src1;
-}
-
-
-static inline C6X_COMPAT_LONG40 _labs(C6X_COMPAT_LONG40 src2)
-{
- long long maxv = (1LL << (40 -1)) - 1;
- long long minv = (-1LL << (40 - 1));
- C6X_COMPAT_LONG40 lres = orig_L40_set(src2);
-
- lres = lres < 0 ? -lres : lres;
- if (lres > maxv) lres = maxv;
- else if (lres < minv) lres = minv;
-
- return lres;
-}
-
-
-static inline C6X_COMPAT_LONG40 _ldotp2(int src1, int src2) {
-return (C6X_COMPAT_LONG40) _dotp2(src1, src2);
-}
-
-
-static inline unsigned int _lmbd(unsigned int src1, unsigned int src2)
-{
- return norm_shift_amt_U_and_non_U(0,(((int) (src1 << 31)) >> 31) ^ (~src2));
-}
-
-
-static inline unsigned int _lnorm(C6X_COMPAT_LONG40 src2) {
-if (src2 == 0)
- return 39;
- else {
- int hi = (int)(src2 >> 32);
- int lo = (int)src2;
-
-
- long long temp = (unsigned long long)(unsigned)lo | (unsigned long long)hi << 32;
- temp = orig_L40_set(temp);
-
- if (temp == 0) return 0;
- int cnt = 0;
- while (((temp >> 39) & 1) == ((temp >> 38) & 1)) {
- temp <<= 1;
- cnt++;
- }
- return cnt;
- }
-}
-
-
-static inline unsigned long long _lo(double src) {
- unsigned long long v;
- *(double*)&v = src;
- return v;
-}
-
-
-static inline unsigned int _loll (long long src)
-{
- return (unsigned int) src;
-}
-
-
-static inline C6X_COMPAT_LONG40 _lsadd(int src1, C6X_COMPAT_LONG40 src2)
-{
- long long maxv = (1LL << (40 -1)) - 1;
- long long minv = (-1LL << (40 - 1));
- int hi = (int)(src2 >> 32);
- int lo = (int)src2;
- long long src2_int = (unsigned long long)(unsigned)lo | (unsigned long long)hi << 32;
-
-
- long long src2_int2 = orig_L40_set(src2_int);
-
- long long res = src1 + src2_int2;
-
- if (res > maxv) {
- res = maxv;
- _overflow = 1;
- }
- else if (res < minv) {
- res = minv;
- _overflow = 1;
- }
-
- long long res2 = orig_L40_set(res);
-
- res2 = (signed char)(res2 >> 32);
-
- C6X_COMPAT_LONG40 lres = (((C6X_COMPAT_LONG40) res2) << 32) | ((unsigned int)res);
- return lres;
-}
-
-
-
-static inline int _max2 (int src1, int src2) {
- short s1[2], s2[2], r[2];
- int result;
- *((int*)s1) = src1;
- *((int*)s2) = src2;
- r[0] = s1[0] > s2[0] ? s1[0] : s2[0];
- r[1] = s1[1] > s2[1] ? s1[1] : s2[1];
- result = *(int*)r;
- return result;
-}
-
-
-
-
-
-
-static inline unsigned int _maxu4(unsigned int src1, unsigned int src2) {
- unsigned int res0, res1, res2, res3;
- unsigned int s1_0 = res0 = (src1 & 0xFF);
- unsigned int s1_1 = res1 = (src1 & 0xFF00) >> 8;
- unsigned int s1_2 = res2 = (src1 & 0xFF0000) >> 16;
- unsigned int s1_3 = res3 = (src1 & 0xFF000000) >> 24;
-
- unsigned int s2_0 = (src2 & 0xFF);
- unsigned int s2_1 = (src2 & 0xFF00) >> 8;
- unsigned int s2_2 = (src2 & 0xFF0000) >> 16;
- unsigned int s2_3 = (src2 & 0xFF000000) >> 24;
-
-// unsigned int res = 0;
-
- if (s1_0 < s2_0)
- res0 = s2_0;
-
- if (s1_1 < s2_1)
- res1 = s2_1;
-
- if (s1_2 < s2_2)
- res2 = s2_2;
-
- if (s1_3 < s2_3)
- res3 = s2_3;
-
- return (res3 << 24) | (res2 << 16) | (res1 << 8) | res0;
-
-
-}
-
-static inline int _min2(int src1, int src2) {
- short s1[2], s2[2], r[2];
- int result;
- *((int*)s1) = src1;
- *((int*)s2) = src2;
- r[0] = s1[0] < s2[0] ? s1[0] : s2[0];
- r[1] = s1[1] < s2[1] ? s1[1] : s2[1];
- result = *(int*)r;
- return result;
-}
-
-
-static inline unsigned int _minu4(unsigned int src1, unsigned int src2) {
-unsigned int res0, res1, res2, res3;
- unsigned int s1_0 = res0 = (src1 & 0xFF);
- unsigned int s1_1 = res1 = (src1 & 0xFF00) >> 8;
- unsigned int s1_2 = res2 = (src1 & 0xFF0000) >> 16;
- unsigned int s1_3 = res3 = (src1 & 0xFF000000) >> 24;
-
- unsigned int s2_0 = (src2 & 0xFF);
- unsigned int s2_1 = (src2 & 0xFF00) >> 8;
- unsigned int s2_2 = (src2 & 0xFF0000) >> 16;
- unsigned int s2_3 = (src2 & 0xFF000000) >> 24;
-
-// unsigned int res = 0;
-
- if (s1_0 > s2_0)
- res0 = s2_0;
-
- if (s1_1 > s2_1)
- res1 = s2_1;
-
- if (s1_2 > s2_2)
- res2 = s2_2;
-
- if (s1_3 > s2_3)
- res3 = s2_3;
-
- return (res3 << 24) | (res2 << 16) | (res1 << 8) | res0;
-}
-
-
-static inline int _mpy(int src1, int src2) {
-return (short) src1 * (short) src2;
-}
-
-
-static inline int _mpyh(int src1, int src2) {
-return (short) (src1 >> 16) * (short) (src2 >> 16);
-}
-
-
-static inline long long _mpyhill (int src1, int src2)
-{
- short s1 = src1 >> 16;
- return ((long long) src2) * s1;
-}
-
-static inline int _mpyhir(int src1, int src2)
-{
- short s1 = src1 >> 16;
- long long result = ((long long) src2) * s1 + (1 << 14);
- result >>= 15;
- return result;
-}
-
-
-static inline int _mpyhl(int src1, int src2) {
-return (short) (src1 >> 16) * (short) (src2);
-}
-
-static inline unsigned int _mpyhlu(unsigned int src1, unsigned int src2) {
-return (unsigned short) (src1 >> 16) * (unsigned short) (src2);
-}
-
-static inline int _mpyhslu(int src1, unsigned int src2) {
-return (short) (src1 >> 16) * (unsigned short) src2;
-}
-
-
-static inline int _mpyhsu(int src1, unsigned int src2) {
-return (short) (src1 >>16) * (unsigned short) (src2 >>16);
-}
-
-
-static inline unsigned int _mpyhu(unsigned int src1, unsigned int src2) {
-return (unsigned short) (src1 >>16) * (unsigned short) (src2 >> 16);
-}
-
-
-static inline int _mpyhuls(unsigned int src1, int src2) {
-return (unsigned short) (src1 >>16) * (signed short) (src2);
-}
-
-
-static inline int _mpyhus(unsigned int src1, int src2) {
-return (unsigned short) (src1 >> 16) * (short) (src2 >>16);
-}
-
-
-
-static inline long long _mpyidll (int src1, int src2)
-{
- return (long long) src1 * src2;
-}
-
-
-static inline int _mpylh(int src1, int src2) {
-return (signed short) (src1 & 0xffff) * (signed short) (src2 >> 16);
-}
-
-static inline unsigned int _mpylhu(unsigned int src1, unsigned int src2) {
-return (unsigned short) src1 * (unsigned short) (src2 >> 16);
-}
-
-
-static inline long long _mpylill (int src1, int src2)
-{
- return ((long long) src2) * ((short)src1);
-}
-
-
-
-static inline int _mpylir(int src1, int src2)
-{
- short s1 = src1;
- long long result = ((long long) src2) * s1 + (1 << 14);
- result >>= 15;
- return result;
-}
-
-
-static inline int _mpylshu(int src1, unsigned int src2) {
-return (short) src1 * (unsigned short) (src2 >> 16);
-}
-
-
-static inline int _mpyluhs(unsigned int src1, int src2) {
-return (unsigned short) src1 * (short) (src2 >> 16);
-}
-
-
-
-static inline int _mpysu(int src1, unsigned int src2) {
-return (short) src1 * (unsigned short) src2;
-}
-
-
-
-static inline long long _mpysu4ll (int src1, unsigned int src2) {
- unsigned short res0, res1, res2, res3;
- signed char s1_0 = (src1 & 0xff);
- signed char s1_1 = (src1 & 0xff00) >> 8;
- signed char s1_2 = (src1 & 0xff0000) >> 16;
- signed char s1_3 = (src1 & 0xff000000) >> 24;
-
- unsigned short s2_0 = (src2 & 0xff);
- unsigned short s2_1 = (src2 & 0xff00) >> 8;
- unsigned short s2_2 = (src2 & 0xff0000) >> 16;
- unsigned short s2_3 = (src2 & 0xff000000) >> 24;
-
- res0 = s1_0 * s2_0;
- res1 = s1_1 * s2_1;
- res2 = s1_2 * s2_2;
- res3 = s1_3 * s2_3;
-
- return (((unsigned long long) res3) << 48)
- | (((unsigned long long) res2) << 32)
- | (((unsigned long long) res1) << 16)
- | res0;
-}
-
-static inline unsigned int _mpyu(unsigned int src1, unsigned int src2) {
- unsigned v = (unsigned short)src1 * (unsigned short)src2;
- return v;
-}
-
-static inline int _mpyus(unsigned int src1, int src2) {
-return (unsigned short) src1 * (short) src2;
-}
-
-static inline long long _mpyu4ll (unsigned int src1, unsigned int src2) {
- unsigned short res0, res1, res2, res3;
- unsigned char s1_0 = (src1 & 0xff);
- unsigned char s1_1 = (src1 & 0xff00) >> 8;
- unsigned char s1_2 = (src1 & 0xff0000) >> 16;
- unsigned char s1_3 = (src1 & 0xff000000) >> 24;
-
- unsigned short s2_0 = (src2 & 0xff);
- unsigned short s2_1 = (src2 & 0xff00) >> 8;
- unsigned short s2_2 = (src2 & 0xff0000) >> 16;
- unsigned short s2_3 = (src2 & 0xff000000) >> 24;
-
- res0 = s1_0 * s2_0;
- res1 = s1_1 * s2_1;
- res2 = s1_2 * s2_2;
- res3 = s1_3 * s2_3;
-
- return (((unsigned long long) res3) << 48)
- | (((unsigned long long) res2) << 32)
- | (((unsigned long long) res1) << 16)
- | res0;
-}
-
-
-static inline long long _mpy2ir(unsigned int src1, unsigned int src2)
-{
- if ((src1 == 0x8000) && (src2 == 0x80000000)) {
- _overflow = 1;
- return 0;
- }
- else {
- short ls1 = src1 & 0xffff;
- short hs1 = src1 >> 16;
- unsigned long long hi = (((long long) hs1) * (int) src2 + (1 << 14)) >> 15;
- unsigned long long lo = ((((long long) ls1) * (int) src2 + (1 << 14)) >> 15) & 0xFFFFFFFF;
- return (hi << 32) | lo;
- }
-}
-
-
-static inline long long _mpy2ll (int src1, int src2) {
- short ls1 = src1 & 0xffff;
- short hs1 = src1 >> 16;
- short ls2 = src2 & 0xffff;
- short hs2 = src2 >> 16;
-
- unsigned long long hi = hs1 * hs2;
- unsigned long long lo = (ls1 * ls2) & 0xFFFFFFFF;
-
- return (hi << 32) | lo;
-
-}
-
-
-static inline int _mpy32(int src1, int src2)
-{
- return src1 * src2;
-}
-
-
-static inline long long _mpy32ll(int src1, int src2)
-{
- return ((long long) src1) * src2;
-}
-
-static inline long long _mpy32su(int src1, unsigned int src2)
-{
- return ((long long) src1) * ((int) src2);
-}
-
-static inline long long _mpy32u(unsigned int src1, unsigned int src2)
-{
- return ((long long) ((int) src1)) * ((long long) ((int) src2));
-}
-
-static inline long long _mpy32us(unsigned int src1, int src2)
-{
- return ((int) src1) * ((long long) src2);
-}
-
-static inline int _mvd (int src2)
-{
- return src2;
-}
-
-
-static inline unsigned int _norm(int src2)
-{
- return norm_shift_amt_U_and_non_U(1,src2);
-}
-
-
-static inline unsigned int _pack2 (unsigned int src1, unsigned int src2) {
- short s1[2], s2[2], r[2];
- int result;
- *((int*)s1) = src1;
- *((int*)s2) = src2;
- r[0] = s2[0];
- r[1] = s1[0];
- result = *(int*)r;
- return result;
-}
-
-
-static inline int _packh2 (unsigned int src1, unsigned int src2) {
- unsigned v0 = src1 & 0xffff0000;
- unsigned v1 = src2 >> 16;
- unsigned v = v0|v1;
- return v;
-
-}
-
-static inline unsigned int _packh4 (unsigned int src1, unsigned int src2) {
- unsigned v3 = (src1 >> 24) & 0xff;
- unsigned v2 = (src1 >> 8) & 0xff;
- unsigned v1 = (src2 >> 24) & 0xff;
- unsigned v0 = (src2 >> 8) & 0xff;
- unsigned v = (v3<<24) | (v2<<16) | (v1 << 8) | v0;
- return v;
-}
-
-static inline unsigned int _packhl2 (unsigned int src1, unsigned int src2) {
- unsigned v0 = src1 & 0xffff0000;
- unsigned v1 = src2 & 0x0000ffff;
- unsigned v = v0|v1;
- return v;
-}
-
-static inline unsigned int _packlh2 (unsigned int src1, unsigned int src2) {
- unsigned v0 = src1 << 16;
- unsigned v1 = (src2 >> 16) & 0xffff;
- unsigned v = v0|v1;
- return v;
-}
-
-
-
-
-static inline unsigned int _packl4 (unsigned int src1, unsigned int src2) {
- unsigned v3 = (src1 >> 16) & 0xff;
- unsigned v2 = (src1) & 0xff;
- unsigned v1 = (src2 >> 16) & 0xff;
- unsigned v0 = (src2) & 0xff;
- unsigned v = (v3<<24) | (v2<<16) | (v1 << 8) | v0;
- return v;
-}
-
-
-
-
-static inline unsigned int _rpack2 (unsigned int src1, unsigned int src2) {
-int s1 = (int) src1;
-int s2 = (int) src2;
-s1 = util_shift_right_saturate_n (s1, -1, 32);
-s2 = util_shift_right_saturate_n (s2, -1, 32);
-return (unsigned int) (s1 & 0xffff0000) | (unsigned int) ((s2 & 0xffff0000) >>16);
-}
-
-
-static inline unsigned int _rotl (unsigned int src1, unsigned int src2)
-{
- src2 &= 0x1f;
- return (src1 << src2) | (src1 >> (32 - src2));
-}
-
-
-static inline int _sadd(int src1, int src2) {
-signed long long res;
-signed long long maxv, minv;
-maxv = (1LL << (32-1)) - 1;
-minv = (-1LL << (32-1));
-res = (long long) src1 + (long long) src2;
-if (res > maxv) {
- res = maxv;
- _overflow = 1;
- }
-else if (res < minv ) {
- res = minv;
- _overflow = 1;
- }
-return (int) res;
-}
-
-static inline long long _saddsub(unsigned int src1, unsigned int src2) {
-int radd;
-signed long long rsub;
-
-signed long long maxv, minv;
-maxv = (1LL << (32-1)) - 1;
-minv = (-1LL << (32-1));
-
-radd = (int) src1 + (int) src2;
-
-// saturate on subtract, not add
-
-
-rsub = (long long) ((int) src1) - (long long) ((int) src2);
-if (rsub > maxv) {
- rsub = maxv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-else if (rsub < minv ) {
- rsub = minv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-
-return (((unsigned long long) radd) << 32) | ( rsub & 0x00000000ffffffff ) ;
-}
-
-
-
-static inline long long _saddsub2(unsigned int src1, unsigned int src2) {
-signed int radd[2];
-signed int rsub[2];
-signed short s1[2], s2[2];
-
-signed int maxv, minv;
-maxv = (1L << (16-1)) - 1;
-minv = (-1L << (16-1));
-
-*((int*)s1) = src1;
-*((int*)s2) = src2;
-
-radd[0] = (int) s1[0] + (int) s2[0];
-radd[1] = (int) s1[1] + (int) s2[1];
-
-rsub[0] = (int) s1[0] - (int) s2[0];
-rsub[1] = (int) s1[1] - (int) s2[1];
-
-if (radd[0] > maxv) {
- radd[0] = maxv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-else if (radd[0] < minv ) {
- radd[0] = minv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-
-if (radd[1] > maxv) {
- radd[1] = maxv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-else if (radd[1] < minv ) {
- radd[1] = minv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-
-
-if (rsub[0] > maxv) {
- rsub[0] = maxv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-else if (rsub[0] < minv ) {
- rsub[0] = minv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-
-if (rsub[1] > maxv) {
- rsub[1] = maxv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-else if (rsub[1] < minv ) {
- rsub[1] = minv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-
-
-return ((((unsigned long long) radd[1]) & 0x000000000000ffff) << 48) |
- ((((unsigned long long) radd[0]) & 0x000000000000ffff) << 32) |
- ((((unsigned long long) rsub[1]) & 0x000000000000ffff) << 16) |
- ((((unsigned long long) rsub[0]) & 0x000000000000ffff));
-}
-
-
-
-static inline int _sadd2(int src1, int src2) {
-signed short s1[2], s2[2];
-signed int r[2], maxv, minv;
-
-maxv = (1L << (16-1)) - 1;
-minv = (-1L << (16-1));
-
-
-*((int*)s1) = src1;
-*((int*)s2) = src2;
-
-r[0] = (int) s1[0] + (int) s2[0];
-r[1] = (int) s1[1] + (int) s2[1];
-
-if (r[0] > maxv) {
- r[0] = maxv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-else if (r[0] < minv ) {
- r[0] = minv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-if (r[1] > maxv) {
- r[1] = maxv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-else if (r[1] < minv ) {
- r[1] = minv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-
-return ((r[1] & 0xffff) << 16 ) | (r[0] & 0xffff) ;
-}
-
-
-static inline int _saddus2(unsigned int src1, int src2) {
-int res0, res1;
- unsigned int s1_0 = (src1 & 0xffff);
- unsigned int s1_1 = (src1 & 0xffff0000) >> 16;
-
- short s2_0 = (src2 & 0xffff);
- short s2_1 = (src2 & 0xffff0000) >> 16;
-
- res0 = s1_0 + s2_0;
- res1 = s1_1 + s2_1;
-
- if (res0 >= 0x10000)
- res0 = 0xffff;
- else if (res0 < 0)
- res0 = 0;
-
- if (res1 >= 0x10000)
- res1 = 0xffff;
- else if (res1 < 0)
- res1 = 0;
-
- return (res1 << 16) | res0;
-}
-
-
-static inline unsigned int _saddu4(unsigned int src1, unsigned int src2) {
-unsigned int res0, res1, res2, res3;
- unsigned int s1_0 = (src1 & 0xff);
- unsigned int s1_1 = (src1 & 0xff00) >> 8;
- unsigned int s1_2 = (src1 & 0xff0000) >> 16;
- unsigned int s1_3 = (src1 & 0xff000000) >> 24;
-
- unsigned int s2_0 = (src2 & 0xff);
- unsigned int s2_1 = (src2 & 0xff00) >> 8;
- unsigned int s2_2 = (src2 & 0xff0000) >> 16;
- unsigned int s2_3 = (src2 & 0xff000000) >> 24;
-
- res0 = s1_0 + s2_0;
- res1 = s1_1 + s2_1;
- res2 = s1_2 + s2_2;
- res3 = s1_3 + s2_3;
-
- if (res0 >= 0x100)
- res0 = 0xff;
-
- if (res1 >= 0x100)
- res1 = 0xff;
-
- if (res2 >= 0x100)
- res2 = 0xff;
-
- if (res3 >= 0x100)
- res3 = 0xff;
-
- return (res3 << 24) | (res2 << 16) | (res1 << 8) | res0;
-
-}
-
-
-
-static inline int _sat(C6X_COMPAT_LONG40 src2)
-{
- long long maxv = (1LL << (32-1)) - 1;
- long long minv = (-1LL << (32-1));
-
- int hi = (int)(src2 >> 32);
- int lo = (int)src2;
- long long temp = (unsigned long long)(unsigned)lo | (unsigned long long)hi << 32;
- temp = orig_L40_set(temp);
-
- if (temp > maxv) {
- temp = maxv;
- _overflow = 1;
- }
- else if (temp < minv) {
- temp = minv;
- _overflow = 1;
- }
- return (int) temp;
-}
-
-static inline unsigned int _set(unsigned int src2, unsigned int csta, unsigned int cstb)
-{
- csta &= 0x1f;
- cstb &= 0x1f;
- if (csta > cstb)
- return src2;
- else {
- unsigned int mask = (((1 << (cstb - csta)) << 1) - 1) << csta;
- return src2 | mask;
- }
-}
-
-static inline unsigned int _setr(unsigned int src2, int src1)
-{
- unsigned int csta = (src1 >> 5) & 0x1f;
- unsigned int cstb = src1 & 0x1f;
- if (csta > cstb)
- return src2;
- else {
- unsigned int mask = (((1 << (cstb - csta)) << 1) - 1) << csta;
- return src2 | mask;
- }
-}
-
-
-static inline unsigned int _shfl (unsigned int src2)
-{
- unsigned short lo = src2;
- unsigned short hi = src2 >> 16;
- unsigned int result = 0;
- int i;
- for (i = 0; i < 32; i+= 2) {
- result >>= 1;
- result |= (lo & 0x1) << 31;
- lo >>= 1;
- result >>= 1;
- result |= (hi & 0x1) << 31;
- hi >>= 1;
- }
- return result;
-}
-
-static inline long long _shfl3 (unsigned int src1, unsigned int src2)
-{
- unsigned short lo = src2;
- unsigned short hi = src1 >> 16;
- unsigned short mid = src1;
- unsigned long long result = 0;
- int i;
- for (i = 0; i < 32; i+= 2) {
- result >>= 1;
- result |= ((unsigned long long) (lo & 0x1)) << 47;
- lo >>= 1;
- result >>= 1;
- result |= ((unsigned long long) (mid & 0x1)) << 47;
- mid >>= 1;
- result >>= 1;
- result |= ((unsigned long long) (hi & 0x1)) << 47;
- hi >>= 1;
- }
- return result;
-}
-
-
-
-static inline unsigned int _shlmb (unsigned int src1, unsigned int src2)
-{
- return (src2 << 8) | (src1 >> 24);
-}
-
-static inline unsigned int _shrmb (unsigned int src1, unsigned int src2)
-{
- return (src2 >> 8) | (src1 << 24);
-}
-
-
-static inline unsigned int _shru2 (unsigned int src1, unsigned int src2) {
-unsigned short hs1 = src1 >> 16;
- unsigned short ls1 = src1 & 0xFFFF;
- hs1 >>= src2;
- ls1 >>= src2;
- return (hs1 << 16) | ls1;
-}
-
-
-static inline int _shr2 (int src1, unsigned int src2) {
- short s1[2], result[2];
- *((int*)s1) = src1;
- src2 = src2 & 31;
- result[0] = (int)s1[0] >> src2;
- result[1] = (int)s1[1] >> src2;
-
- return *(int*)result;
-}
-
-
-static inline int _smpy (int src1, int src2) {
-unsigned long long result;
-result = (((short) src1 * (short) src2) << 1);
-
-if ((result & 0xffffffff) == 0x80000000){
- result = 0x7fffffff;
- _overflow = 1;
- }
-return (int) (result);
-}
-
-static inline int _smpyh (int src1, int src2) {
-unsigned long long result;
-result = ((short) (src1 >> 16) * (short) (src2 >> 16)) << 1;
-if ((result & 0xffffffff) == 0x80000000){
- result = 0x7fffffff;
- _overflow = 1;
- }
-return (int) (result);
-}
-
-static inline int _smpyhl (int src1, int src2) {
-unsigned long long result;
-result = ((short) (src1 >> 16) * (short) (src2)) << 1;
-if ((result & 0xffffffff) == 0x80000000){
- result = 0x7fffffff;
- _overflow = 1;
- }
-return (int) (result);
-}
-
-static inline int _smpylh (int src1, int src2) {
-unsigned long long result;
-result = ((short) (src1) * (short) (src2 >> 16)) << 1;
-if ((result & 0xffffffff) == 0x80000000){
- result = 0x7fffffff;
- _overflow = 1;
- }
-return (int) (result);
-}
-
-static inline long long _smpy2ll (int src1, int src2) {
- short ls1 = src1 & 0XFFFF;
- short hs1 = src1 >> 16;
- short ls2 = src2 & 0XFFFF;
- short hs2 = src2 >> 16;
-
- unsigned long long hi = (hs1 * hs2) << 1;
- unsigned long long lo = ((ls1 * ls2) << 1) & 0xFFFFFFFF;
- if ((hi & 0xffffffff) == 0x80000000){
- hi = 0x7fffffff;
- _overflow = 1;
- }
-
- if ((lo & 0xffffffff) == 0x80000000){
- lo = 0x7fffffff;
- _overflow = 1;
- }
-
- return (hi << 32) | lo;
-}
-
-
-
-
-static inline int _smpy32(int src1, int src2)
-{
- long long res = (long long) src1 * src2;
- res <<= 1;
- res >>= 32;
- return res;
-}
-
-static inline unsigned char TEN_satu8 (short src)
-{
- if (src > 0xff)
- return 0xff;
- else if (src < 0)
- return 0;
- else
- return src;
-}
-
-static inline int _spack2 (int src1, int src2) {
-short s1 = (short) util_saturate_n_no_state(src1,16);
-short s2 = (short) util_saturate_n_no_state(src2,16);
-return ( (unsigned int) s1 << 16) | (((int) s2) & 0xFFFF);
-}
-
-
-static inline unsigned int _spacku4 (int src1, int src2) {
- short lolo = src2;
- short lohi = src2 >> 16;
- short hilo = src1;
- short hihi = src1 >> 16;
-
- lolo = TEN_satu8(lolo);
- lohi = TEN_satu8(lohi);
- hilo = TEN_satu8(hilo);
- hihi = TEN_satu8(hihi);
-
- return (((unsigned int) hihi) << 24) | (((unsigned int) hilo) << 16) | (lohi << 8) | lolo;
-}
-
-
-
-static inline int _sshl (int src1, unsigned int src2) {
-short local2 = (short)(src2 & 0x7FFF);
-return (int) util_shift_right_saturate_n(src1, -local2, 32);
-}
-
-
-
-
-static inline int _sshvl (int src2, int src1) {
- short s1;
- if (src1 > 31)
- s1 = 31;
- else if (src1 < -31)
- s1 = -31;
- else
- s1 = src1;
-
- return (int) util_shift_right_saturate_n(src2, -s1, 32);
-}
-
-
-
-
-
-static inline int _sshvr (int src2, int src1) {
-short s1;
- if (src1 > 31)
- s1 = 31;
- else if (src1 < -31)
- s1 = -31;
- else
- s1 = src1;
- return (int) util_shift_right_saturate_n(src2, s1, 32);
-}
-
-
-
-
-static inline int _ssub(int src1, int src2) {
-signed long long res;
-signed long long maxv, minv;
-maxv = (1LL << (32-1)) - 1;
-minv = (-1LL << (32-1));
-res = (long long) src1 - (long long) src2;
-if (res > maxv) {
- res = maxv;
- _overflow = 1;
- }
-else if (res < minv ) {
- res = minv;
- _overflow = 1;
- }
-return (int) res;
-}
-
-static inline int _ssub2(int src1, int src2) {
-signed short s1[2], s2[2];
-signed int r[2], maxv, minv;
-
-maxv = (1L << (16-1)) - 1;
-minv = (-1L << (16-1));
-
-
-*((int*)s1) = src1;
-*((int*)s2) = src2;
-
-r[0] = (int) s1[0] - (int) s2[0];
-r[1] = (int) s1[1] - (int) s2[1];
-
-if (r[0] > maxv) {
- r[0] = maxv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-else if (r[0] < minv ) {
- r[0] = minv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-if (r[1] > maxv) {
- r[1] = maxv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-else if (r[1] < minv ) {
- r[1] = minv;
- /* NOTE: TI c6x does NOT set the overflow register even if results saturate */
- /* _overflow = 1; */
- }
-
-return ((r[1] & 0xffff) << 16 ) | (r[0] & 0xffff) ;
-}
-
-
-static inline int _subabs4 (int src1, int src2) {
- int res0, res1, res2, res3;
- unsigned int s1_0 = (src1 & 0xff);
- unsigned int s1_1 = (src1 & 0xff00) >> 8;
- unsigned int s1_2 = (src1 & 0xff0000) >> 16;
- unsigned int s1_3 = (src1 & 0xff000000) >> 24;
-
- unsigned int s2_0 = (src2 & 0xff);
- unsigned int s2_1 = (src2 & 0xff00) >> 8;
- unsigned int s2_2 = (src2 & 0xff0000) >> 16;
- unsigned int s2_3 = (src2 & 0xff000000) >> 24;
-
- res0 = s1_0 - s2_0;
- res1 = s1_1 - s2_1;
- res2 = s1_2 - s2_2;
- res3 = s1_3 - s2_3;
-
- if (res0 < 0)
- res0 = -res0;
-
- if (res1 < 0)
- res1 = -res1;
-
- if (res2 < 0)
- res2 = -res2;
-
- if (res3 < 0)
- res3 = -res3;
-
- return (res3 << 24) | (res2 << 16) | (res1 << 8) | res0;
-}
-
-
-static inline unsigned int _subc (unsigned int src1, unsigned int src2)
-{
- if ( src1 >= src2)
- return ((src1 - src2) << 1) + 1;
- else
- return src1 << 1;
-}
-
-
-
-static inline int _sub2(int src1, int src2) {
- short s1[2], s2[2], r[2];
- int result;
- *((int*)s1) = src1;
- *((int*)s2) = src2;
- r[0] = s1[0] - s2[0];
- r[1] = s1[1] - s2[1];
- result = *(int*)r;
- return result;
-}
-
-
-static inline int _sub4(int src1, int src2) {
- char c1[4], c2[4], r[4];
- int result;
- *((int*)c1) = src1;
- *((int*)c2) = src2;
- r[0] = c1[0] - c2[0];
- r[1] = c1[1] - c2[1];
- r[2] = c1[2] - c2[2];
- r[3] = c1[3] - c2[3];
- result = *(int*)r;
- return result;
-}
-
-
-static inline int _swap4 (unsigned int src1) {
- unsigned char v0 = src1;
- unsigned char v1 = src1 >> 8;
- unsigned char v2 = src1 >> 16;
- unsigned char v3 = src1 >> 24;
- unsigned v = v0<<8 | v1 | v2<<24 | v3<<16;
- return v;
-}
-
-static inline unsigned int _unpkhu4 (unsigned int src1) {
- unsigned v0 = src1>>24;
- unsigned v1 = (src1>>16) & 0xff;
- return (v0<<16) | v1;
-}
-
-static inline unsigned int _unpklu4 (unsigned int src1) {
- unsigned v1 = (src1>>8) & 0xff;
- unsigned v0 = (src1) & 0xff;
- return (v1<<16) | v0;
-}
-
-
-
-
-static inline unsigned int _xpnd2 (unsigned int src1) {
- int v0 = (src1 & 0x1) ? 0x0000ffff : 0x00000000;
- int v1 = (src1 & 0x2) ? 0xffff0000 : 0x00000000;
- return v0|v1;
-}
-
-static inline unsigned int _xpnd4 (unsigned int src1) {
- int v0 = (src1 & 0x1) ? 0x000000ff : 0x00000000;
- int v1 = (src1 & 0x2) ? 0x0000ff00 : 0x00000000;
- int v2 = (src1 & 0x4) ? 0x00ff0000 : 0x00000000;
- int v3 = (src1 & 0x8) ? 0xff000000 : 0x00000000;
- int r = v0|v1|v2|v3;
- return r;
-}
-
-
-
-// end of Implemented in alphabetical order
-
-
-#endif /* __C6X_COMPAT__H */
diff --git a/components/esp32/include/xtensa/core-macros.h b/components/esp32/include/xtensa/core-macros.h
index c8f7e34762..37c48921a4 100644
--- a/components/esp32/include/xtensa/core-macros.h
+++ b/components/esp32/include/xtensa/core-macros.h
@@ -335,7 +335,7 @@
__asm__ __volatile__("wsr.intenable %0" :: "a"(__intenable):"memory"); \
} while(0)
# define XTHAL_GET_INTERRUPT() ({ int __interrupt; \
- __asm__("rsr.interrupt %0" : "=a"(__interrupt)); \
+ __asm__ __volatile__("rsr.interrupt %0" : "=a"(__interrupt)); \
__interrupt; })
# define XTHAL_SET_INTSET(v) do { int __interrupt = (int)(v); \
__asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); \
@@ -344,7 +344,7 @@
__asm__ __volatile__("wsr.intclear %0" :: "a"(__interrupt):"memory"); \
} while(0)
# define XTHAL_GET_CCOUNT() ({ int __ccount; \
- __asm__("rsr.ccount %0" : "=a"(__ccount)); \
+ __asm__ __volatile__("rsr.ccount %0" : "=a"(__ccount)); \
__ccount; })
# define XTHAL_SET_CCOUNT(v) do { int __ccount = (int)(v); \
__asm__ __volatile__("wsr.ccount %0" :: "a"(__ccount):"memory"); \
diff --git a/components/esp32/include/xtensa/debugfs.h b/components/esp32/include/xtensa/debugfs.h
deleted file mode 100644
index eba7b438cd..0000000000
--- a/components/esp32/include/xtensa/debugfs.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Xtensa Debug-FileSystem definitions */
-
-/*
- * Copyright (c) 2005-2009 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-#ifndef __DEBUGFS_H__
-#define __DEBUGFS_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include
-#include
-#include
-
-int xt_dbfs_open(const char *pathname, int flags, mode_t mode);
-int xt_dbfs_ftruncate(int fd, off_t length);
-int xt_dbfs_truncate(const char * filename, off_t length);
-int xt_dbfs_creat(const char *pathname, mode_t mode);
-int xt_dbfs_errno(void);
-int xt_dbfs_lseek(int fd, off_t offset, int whence);
-ssize_t xt_dbfs_write(int fd, const void * buf, size_t bytes);
- ssize_t xt_dbfs_open_append_close(const char * filename, int align,
- const void * buf, size_t bytes);
-ssize_t xt_dbfs_read(int fd, void * buf, size_t bytes);
-int xt_dbfs_close(int fd);
-int xt_dbfs_unlink(const char *pathname);
-
-/* By default, this function is a wrapper around sbrk, and follows
- sbrk semantics:
-
- On success, it returns increment bytes of memory allocated from
- system memory.
-
- On failure, it returns 0xFFFFFFFF
-
-
- If you want to use a method of allocating memory other than sbrk,
- implement xt_dbfs_sbrk in your own sources, and the linker will
- automatically use that copy.
-*/
-void * xt_dbfs_sbrk(int increment);
-
-
-
-#ifdef REPLACE_FS_WITH_DBFS
-#define open xt_dbfs_open
-#define close xt_dbfs_close
-#define creat xt_dbfs_creat
-#define lseek xt_dbfs_lseek
-#define write xt_dbfs_write
-#define read xt_dbfs_read
-#define close xt_dbfs_close
-#define unlink xt_dbfs_unlink
-
-#define rmdir NOT_IMPLEMENTED_IN_DBFS
-#define opendir NOT_IMPLEMENTED_IN_DBFS
-#define closedir NOT_IMPLEMENTED_IN_DBFS
-#define dirfs NOT_IMPLEMENTED_IN_DBFS
-#define readdir NOT_IMPLEMENTED_IN_DBFS
-#define scandir NOT_IMPLEMENTED_IN_DBFS
-#define seekdir NOT_IMPLEMENTED_IN_DBFS
-#define telldir NOT_IMPLEMENTED_IN_DBFS
-
-#define fcntl NOT_IMPLEMENTED_IN_DBFS
-#define dup2 NOT_IMPLEMENTED_IN_DBFS
-#define dup NOT_IMPLEMENTED_IN_DBFS
-#define flock NOT_IMPLEMENTED_IN_DBFS
-#define lockf NOT_IMPLEMENTED_IN_DBFS
-#define link NOT_IMPLEMENTED_IN_DBFS
-#define stat NOT_IMPLEMENTED_IN_DBFS
-#define fstat NOT_IMPLEMENTED_IN_DBFS
-#define lstat NOT_IMPLEMENTED_IN_DBFS
-#define chmod NOT_IMPLEMENTED_IN_DBFS
-#define fchmod NOT_IMPLEMENTED_IN_DBFS
-#define chmown NOT_IMPLEMENTED_IN_DBFS
-#define lchown NOT_IMPLEMENTED_IN_DBFS
-#define fchown NOT_IMPLEMENTED_IN_DBFS
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/components/esp32/include/xtensa/feedback.h b/components/esp32/include/xtensa/feedback.h
deleted file mode 100644
index aecb745333..0000000000
--- a/components/esp32/include/xtensa/feedback.h
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/*
- * Copyright (c) 2013 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-#ifndef __XT_FEEDBACK_INCLUDED__
-#define __XT_FEEDBACK_INCLUDED__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* xt_feedback_save_and_reset
-
- Save and reset the accumulated feedback data.
-*/
-extern void xt_feedback_save_and_reset(void);
-
-/* xt_feedback_enable
-
- Turn on feedback accumulation. Ordinarily, feedback accumulation is on
- by default. If you turn it off using xt_feedback_disable, You can turn
- it on again via this function.
-*/
-extern void xt_feedback_enable (void);
-
-/* xt_feedback_disable
-
- Turn off feedback accumulation. If you don't want to gather feedback for a
- portion of your code, use this function and then xt_feedback_enable when
- you want to start again.
-*/
-extern void xt_feedback_disable (void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XT_FEEDBACK_INCLUDED__ */
-
diff --git a/components/esp32/include/xtensa/gdbio.h b/components/esp32/include/xtensa/gdbio.h
deleted file mode 100644
index 784a862978..0000000000
--- a/components/esp32/include/xtensa/gdbio.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Xtensa Debug-FileSystem definitions
- *
- * Copyright (c) 2006-2009 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-#ifndef __DEBUGFS_H__
-#define __DEBUGFS_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include
-#include
-#include
-#include
-
- int _gdbio_open_r(void * ptr, const char *pathname, int flags, mode_t mode);
- int _gdbio_creat_r(void * ptr, const char *pathname, mode_t mode);
- int _gdbio_lseek_r(void * ptr, int fd, off_t offset, int whence);
- ssize_t _gdbio_write_r(void * ptr, int fd, const void * buf, size_t bytes);
- ssize_t _gdbio_read_r(void * ptr, int fd, void * buf, size_t bytes);
- int _gdbio_close_r(void * ptr, int fd);
- int _gdbio_unlink_r(void * ptr, const char * pathname);
-
- static inline
- int gdbio_open(const char *pathname, int flags, mode_t mode) {
- return _gdbio_open_r(&errno, pathname, flags, mode);
- }
- static inline int
- gdbio_creat(const char *pathname, mode_t mode) {
- return _gdbio_open_r(&errno, pathname, O_CREAT|O_WRONLY|O_TRUNC, mode);
- }
- static inline int
- gdbio_errno(void) {
- return errno;
- }
- static inline int
- gdbio_lseek(int fd, off_t offset, int whence) {
- return _gdbio_lseek_r(&errno, fd, offset, whence);
- }
- static inline
- ssize_t gdbio_write(int fd, const void * buf, size_t bytes) {
- return _gdbio_write_r(&errno, fd, buf, bytes);
- }
- static inline
- ssize_t gdbio_read(int fd, void * buf, size_t bytes) {
- return _gdbio_read_r(&errno, fd, buf, bytes);
- }
- static inline int
- gdbio_close(int fd) {
- return _gdbio_close_r(&errno, fd);
- }
- static inline int
- gdbio_unlink(const char * pathname) {
- return _gdbio_unlink_r(&errno, pathname);
- }
-
-#ifdef REPLACE_FS_WITH_GDBIO
-#define open gdbio_open
-#define close gdbio_close
-#define creat gdbio_creat
-#define lseek gdbio_lseek
-#define write gdbio_write
-#define read gdbio_read
-#define close gdbio_close
-#define unlink gdbio_unlink
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/components/esp32/include/xtensa/jtag-xtensa.h b/components/esp32/include/xtensa/jtag-xtensa.h
deleted file mode 100644
index 45ac1caa40..0000000000
--- a/components/esp32/include/xtensa/jtag-xtensa.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Copyright (c) 2011-2012 Tensilica Inc. ALL RIGHTS RESERVED.
-// These coded instructions, statements, and computer programs are the
-// copyrighted works and confidential proprietary information of Tensilica Inc.
-// They may not be modified, copied, reproduced, distributed, or disclosed to
-// third parties in any manner, medium, or form, in whole or in part, without
-// the prior written consent of Tensilica Inc.
-*/
-
-#ifndef _JTAG_XTENSA_H_
-#define _JTAG_XTENSA_H_
-
-
-/* ---------------- JTAG registers ------------------ */
-
-/* -- ER and later JTAG registers */
-typedef enum {
- regIR,
- regBypass,
- regNAR,
- regNDR,
- regIdcode,
- regPWRCTL,
- regPWRSTAT,
- regJtagMAX,
-} xtensaJtagReg;
-
-/* -- pre-ER JTAG registers */
-typedef enum {
- regOldIR,
- regOldBypass,
- regOldDIRW,
- regOldDIR,
- regOldDDR,
- regOldDOSR,
- regOldESR,
- regOldDCR,
- regOldTraxNDR,
- regOldTraxNAR,
- regOldMAX
-} xtensaOldJtagReg;
-
-
-/* ---------------- JTAG Instructions ------------------ */
-
-/* -- pre-ER JTAG instructions */
-typedef enum {
- ji_EnableOCD = 0x11,
- ji_DebugInt,
- ji_RetDebugInt, // TBD: remove
- ji_DisRetOCD, // TBD: remove
- ji_ExecuteDI,
- ji_LoadDI,
- ji_ScanDDR,
- ji_ReadDOSR,
- ji_ScanDCR,
- ji_LoadWDI,
- ji_TRAX = 0x1c,
- ji_BYPASS = 0x1f,
-} xtensaJtagInstruction;
-
-typedef enum {
- OCDNormalMode,
- OCDRunMode,
- OCDHaltMode,
- OCDStepMode
-} xtensaMode;
-
-typedef struct {
- xtensaMode mode;
- int DRsel;
- XTMP_core core;
- XTMP_tap tap;
- int core_num;
- jtagReg_t *jtagRegs;
- void *dap; // used for ARM DAP only
- bool isBig;
- int dir_array_option; // used by pre-ER devices only
- // for testing, below - FIXME - delete later
- int ocdReg;
- unsigned int wr_data;
- XTMP_event start_OCD_trans;
- bool data_cycle;
- bool data_pending;
-} coreSlaveData_t;
-
-
-enum OCD_ACCESS_TYPE{
- NEXUS_ACCESS,
- CS_ACCESS,
-};
-
-// pre-ER Xtensa initializiation
-EXTERN XTMP_deviceStatus
-XTMP_jtagCoreSlaveEX(XTMP_component component, XTMP_jtagSlave slave, void* mydata);
-
-extern char *OCDrd;
-extern char *OCDwr;
-
-#endif
diff --git a/components/esp32/include/xtensa/lcd-splc780d-4bitmode-board.h b/components/esp32/include/xtensa/lcd-splc780d-4bitmode-board.h
deleted file mode 100644
index f4db588582..0000000000
--- a/components/esp32/include/xtensa/lcd-splc780d-4bitmode-board.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*******************************************************************************
-Copyright (c) 2009-2013 by Tensilica Inc. ALL RIGHTS RESERVED.
-These coded instructions, statements, and computer programs are the
-copyrighted works and confidential proprietary information of Tensilica Inc.
-They may not be modified, copied, reproduced, distributed, or disclosed to
-third parties in any manner, medium, or form, in whole or in part, without
-the prior written consent of Tensilica Inc.
---------------------------------------------------------------------------------
-
-lcd-splc780d-4bitmode-board.h Board-specific LCD info for these boards:
- Avnet AV110 (XT-AV110)
- Xilinx ML605 (XT-ML605)
- Xilinx KC705 (XT-KC705)
-
-Interface between board-independent driver and board-specific header.
-
-This is used by a board-independent SPLC780D LCD controller (4 bit mode)
-driver to obtain board-specific information about LCD displays on the board,
-such as the controller register base address and spacing (a function of how
-the address lines are connected on the board) and length of the visible window
-of the display (a function of the LCD panel the controller drives).
-The driver doesnot refer directly to the board-specific header, which therefore is not
-constrained to use macro names consistent with other boards.
-
-!! Must not contain any board-specific macro names (only controller specific) !!
-
-Included at compile-time via an include path specific to the board.
-
-The listed boards contain a single MYTech MOC-16216B-B display driven by
-a Sunplus SPLC870D controller.
-
-*******************************************************************************/
-
-#ifndef _LCD_SPLC780D_4BIT_BOARD_H
-#define _LCD_SPLC780D_4BIT_BOARD_H
-
-#include /* Board info */
-
-
-/* Base address of the controller's registers. */
-#ifdef SPLC780D_4BIT_VADDR
-#define SPLC780D_4BIT_REGBASE SPLC780D_4BIT_VADDR
-#endif
-
-/*
-The controller's registers are connected at word addresses on these boards.
-Each byte-wide register appears as the least-significant-byte (LSB) of the
-word regardless of the endianness of the processor (so if using word accesses
-then endianness doesn't matter).
-*/
-#define SPLC780D_4BIT_REGSPACING 4
-typedef unsigned splc780d_4bit_reg_t;
-
-/* Include generic information shared by all boards that use this device. */
-#include
-
-
-/* Display limits of the LCD panel. */
-#define DISPLAY_VISIBLE_LEN 16 /* length (chars) of visible window */
-
-#endif /* _LCD_SPLC780D_4BIT_BOARD_H */
-
diff --git a/components/esp32/include/xtensa/lcd-splc780d-4bitmode.h b/components/esp32/include/xtensa/lcd-splc780d-4bitmode.h
deleted file mode 100644
index 0a214bb400..0000000000
--- a/components/esp32/include/xtensa/lcd-splc780d-4bitmode.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*******************************************************************************
-
-Copyright (c) 2009-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
-These coded instructions, statements, and computer programs are the
-copyrighted works and confidential proprietary information of Tensilica Inc.
-They may not be modified, copied, reproduced, distributed, or disclosed to
-third parties in any manner, medium, or form, in whole or in part, without
-the prior written consent of Tensilica Inc.
---------------------------------------------------------------------------------
-
-lcd-SPLC780D-4bitmode.h Generic definitions for Sunplus SPLC780D LCD Controller
-operating in 4 bit mode.
-
-This is used by board-support-packages with one or more LCD displays that use
-a SPLC780D controller in 4 bit mode. A BSP provides a base address for each
-instance of an SPLC780D LCD controller on the board.
-
-Note that LCD display operation is almost totally independent of the LCD
-display, depending almost entirely on the controller. However the display
-may limit the number of characters of the controller's RAM buffer that are
-actually visible at one time. The length of the display's visible window
-is not specifified in this controller-specific header, but comes to the
-driver from the board-specific "display.h" header.
-
-*******************************************************************************/
-
-#ifndef _LCD_SPLC780D_4BIT_H_
-#define _LCD_SPLC780D_4BIT_H_
-
-
-/* Offsets to controller registers from base. */
-#define SPLC780D_4BIT_INST 0
-#define SPLC780D_4BIT_DATA (SPLC780D_4BIT_INST + SPLC780D_4BIT_REGSPACING)
-
-
-#define SPLC780D_4BIT_INST_INIT1 0xFF /* First command in
- init sequence */
-#define SPLC780D_4BIT_INST_INIT2 0x30 /* Second command in
- init sequence,
- issued 3 times */
-#define SPLC780D_4BIT_INST_INIT3 0x20 /* Third and last command
- in init sequence */
-#define SPLC780D_4BIT_INST_CLEAR 0x01 /* clear (blank) display) */
-#define SPLC780D_4BIT_INST_SET_MODE 0x28 /* Set LCD mode. Supported
- setting is 4 bit data
- length, 2 lines, 5*8 */
-#define SPLC780D_4BIT_INST_DSPLY_ON 0x0C /* Set Display ON */
-#define SPLC780D_4BIT_INST_CRSR_INC 0x06 /* Set cursor moving direction
- as increment */
-
-#define SPLC780D_4BIT_LINET_ADDR 0x80 /* clear (blank) display) */
-#define SPLC780D_4BIT_LINEB_ADDR 0xC0 /* clear (blank) display) */
-
-#ifndef __ASSEMBLER__
-
-/* C interface to controller registers. */
-struct splc780d_4bit_s {
- splc780d_4bit_reg_t inst; /* instruction register */
- splc780d_4bit_reg_t data; /* data register */
-};
-
-typedef volatile struct splc780d_4bit_s splc780d_4bit_t;
-
-/*
-Prototypes of high level driver functions.
-*/
-
-/* Write an instruction byte to LCD, result in two back to back writes since the
- * LCD is hooked up in 4 bit mode*/
-extern void lcd_write_inst_byte(splc780d_4bit_t *lcd, unsigned char inst);
-
-/* Write a data byte to LCD, result in two back to back writes since the
- * LCD is hooked up in 4 bit mode*/
-extern void lcd_write_data_byte(splc780d_4bit_t *lcd, unsigned char data);
-
-/*
-Initialize the display with default settings.
-*/
-extern void splc780d_4bit_init_default(splc780d_4bit_t *lcd);
-
-/*
-Write a single character at a given position (chars from left, starting at 0).
-Wait long enough afterward for the controller to be ready for more input.
-Positions beyond the end of the display are ignored.
-*/
-extern void splc780d_4bit_write_char(splc780d_4bit_t *lcd, unsigned pos, const char c);
-
-/*
-Write a string to the display starting at the left (position 0).
-Blank-pad to or truncate at the end of the display (overwrites any previous
-string so don't need to blank the display first).
-Wait long enough after each char for the controller to be ready for more input.
-*/
-extern void splc780d_4bit_write_string(splc780d_4bit_t *lcd, const char *s);
-
-/*
-Blank (clear) the entire display.
-Wait long enough afterward for the controller to be ready for more input.
-*/
-extern void splc780d_4bit_blank(splc780d_4bit_t *lcd);
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _LCD_SPLC780D_4BIT_H_ */
-
diff --git a/components/esp32/include/xtensa/lcd-splc780d.h b/components/esp32/include/xtensa/lcd-splc780d.h
deleted file mode 100644
index 4e878e9053..0000000000
--- a/components/esp32/include/xtensa/lcd-splc780d.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*******************************************************************************
-
-Copyright (c) 2006-2007 by Tensilica Inc. ALL RIGHTS RESERVED.
-These coded instructions, statements, and computer programs are the
-copyrighted works and confidential proprietary information of Tensilica Inc.
-They may not be modified, copied, reproduced, distributed, or disclosed to
-third parties in any manner, medium, or form, in whole or in part, without
-the prior written consent of Tensilica Inc.
---------------------------------------------------------------------------------
-
-lcd-SPLC780D.h Generic definitions for Sunplus SPLC780D LCD Controller
-
-This is used by board-support-packages with one or more LCD displays that use
-a SPLC780D controller. A BSP provides a base address for each instance of an
-SPLC780D LCD controller on the board.
-
-Note that LCD display operation is almost totally independent of the LCD
-display, depending almost entirely on the controller. However the display
-may limit the number of characters of the controller's RAM buffer that are
-actually visible at one time. The length of the display's visible window
-is not specifified in this controller-specific header, but comes to the
-driver from the board-specific "display.h" header.
-
-*******************************************************************************/
-
-#ifndef _LCD_SPLC780D_H_
-#define _LCD_SPLC780D_H_
-
-
-/* Offsets to controller registers from base. */
-#define SPLC780D_INST 0
-#define SPLC780D_DATA (SPLC780D_INST + SPLC780D_REGSPACING)
-
-/*
-Bit fields and their values in the instruction register.
-These fields are NOT orthogonal - they overlap!
-Thus only one field may be written at a time, determined by the
-most-significant 1 bit in the pattern (the field selector).
-All less significant bits are part of the value of the selected field.
-The fields and their values are grouped together to emphasize this format.
-Field selector macro names end in '_' (implying something more needs
-to be ORed) and the value macros are indented. The pattern written to a
-bitfield is a bitwise OR of a field selector and one or more values, eg.
- (SPLC780D_INST_ON_ | SPLC780D_INST_ON_DISPLAY | SPLC780D_INST_ON_CURSOR)
-A single bit field (eg. SPCL780D_INST_HOME) need not have a value.
-
-NOTE: Controller requires a software delay after writing to the control
-or data registers. For the data register it is 38us. For the control
-register it is 38us for most bit fields, with the following exceptions:
- SPLC780D_FUNC_ 100us.
- SPLC780D_INST_CLEAR, SPLC780D_INST_HOME 1520us.
-For more details and reset timing, see the SUNPLUS SPLC780D data sheet.
-*/
-
-#define SPLC780D_INST_CLEAR_ 0x1 /* clear (blank) display) */
-
-#define SPLC780D_INST_HOME_ 0x2 /* home cursor and shift pos */
-
-#define SPLC780D_INST_ENTRY_ 0x4 /* combine *ENTRY_* flags below */
-#define SPLC780D_INST_ENTRY_SHIFT 0x1 /* display shift on entry / not */
-#define SPLC780D_INST_ENTRY_INCR 0x2 /* cursor incr / decr */
-#define SPLC780D_INST_ENTRY_DECR 0 /* cursor incr / decr */
-
-#define SPLC780D_INST_ON_ 0x8 /* combine *ON_* flags below */
-#define SPLC780D_INST_ON_DISPLAY 0x4 /* display on / off */
-#define SPLC780D_INST_ON_CURSOR 0x2 /* cursor on / off */
-#define SPLC780D_INST_ON_BLINK 0x1 /* blink on / off */
-
-#define SPLC780D_INST_SHIFT_ 0x10 /* combine *SHIFT_* flags below */
-#define SPLC780D_INST_SHIFT_DISP 0x8 /* shift display / move cursor */
-#define SPLC780D_INST_SHIFT_CURS 0 /* shift display / move cursor */
-#define SPLC780D_INST_SHIFT_RIGHT 0x4 /* shift right / left */
-#define SPLC780D_INST_SHIFT_LEFT 0 /* shift right / left */
-
-#define SPLC780D_INST_FUNC_ 0x20 /* combine *FUNC_* flags below */
-#define SPLC780D_INST_FUNC_8BIT 0x10 /* data length 8 bit / 4 bit */
-#define SPLC780D_INST_FUNC_4BIT 0 /* data length 8 bit / 4 bit */
-#define SPLC780D_INST_FUNC_2LINE 0x08 /* display lines 2 / 1 */
-#define SPLC780D_INST_FUNC_1LINE 0 /* display lines 2 / 1 */
-#define SPLC780D_INST_FUNC_F5x10 0x04 /* character font 5x10 / 5x8 */
-#define SPLC780D_INST_FUNC_F5x8 0 /* character font 5x10 / 5x8 */
- /* font must be 5x8 for 2 lines */
-#define SPLC780D_INST_CGEN_ 0x40 /* set char generator address */
-#define SPLC780D_INST_CGEN_ADDR 0x3F /* to address in this field */
-#define SPLC780D_INST_DRAM_ 0x80 /* set display data RAM address */
-#define SPLC780D_INST_DRAM_ADDR 0x7F /* to address in this field */
-#define SPLC780D_INST_DRAM_LINE2 0x40 /* address offset to line 2 */
-/* Controller limits */
-#define SPLC780D_RAMLEN_1LINE 0x50 /* length of line in RAM (1 line) */
-#define SPLC780D_RAMLEN_2LINE 0x28 /* length of line in RAM (2 line) */
-
-
-#ifndef __ASSEMBLER__
-
-/* C interface to controller registers. */
-struct splc780d_s {
- splc780d_reg_t inst; /* instruction register */
- splc780d_reg_t data; /* data register */
-};
-
-typedef volatile struct splc780d_s splc780d_t;
-
-/*
-Prototypes of high level driver functions.
-*/
-
-/*
-Initialize the display with the FUNC_, ENTRY_ and ON_ fields as specified in
-terms of the values above. The splc780d_init_default() macro is an example.
-*/
-extern void splc780d_init(splc780d_t *lcd,
- unsigned func, unsigned entry, unsigned on);
-
-/*
-Initialize the display to default mode: 8-bit interface, 2 line, 5x8 font,
-increment cursor on entry, display on (cursor and blinking off).
-*/
-#define splc780d_init_default(lcd) \
- splc780d_init( lcd, \
- SPLC780D_INST_FUNC_8BIT \
- | SPLC780D_INST_FUNC_2LINE \
- | SPLC780D_INST_FUNC_F5x8, \
- SPLC780D_INST_ENTRY_INCR, \
- SPLC780D_INST_ON_DISPLAY \
- )
-
-/*
-Write a single character at a given position (chars from left, starting at 0).
-Wait long enough afterward for the controller to be ready for more input.
-Positions beyond the end of the display are ignored.
-*/
-extern void splc780d_write_char(splc780d_t *lcd, unsigned pos, const char c);
-
-/*
-Write a string to the display starting at the left (position 0).
-Blank-pad to or truncate at the end of the display (overwrites any previous
-string so don't need to blank the display first).
-Wait long enough after each char for the controller to be ready for more input.
-*/
-extern void splc780d_write_string(splc780d_t *lcd, const char *s);
-
-/*
-Blank (clear) the entire display.
-Wait long enough afterward for the controller to be ready for more input.
-*/
-extern void splc780d_blank(splc780d_t *lcd);
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _LCD_SPLC780D_H_ */
-
diff --git a/components/esp32/include/xtensa/overlay.h b/components/esp32/include/xtensa/overlay.h
deleted file mode 100644
index e959cf512f..0000000000
--- a/components/esp32/include/xtensa/overlay.h
+++ /dev/null
@@ -1,184 +0,0 @@
-// overlay.h -- Overlay manager header file
-// $Id$
-
-// Copyright (c) 2013 Tensilica Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-#ifndef OVERLAY_H
-#define OVERLAY_H
-
-
-#include
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Define this to turn off overlay support
-#ifdef XT_DISABLE_OVERLAYS
-
-#define OVERLAY(n)
-#define DECLARE_OVERLAY(n)
-
-#define xt_overlay_map(ov_id)
-#define xt_overlay_map_async(ov_id) 0
-#define xt_overlay_map_in_progress() 0
-#define xt_overlay_get_id() 0
-#define xt_overlay_get_state(pc) 0
-#define xt_overlay_check_map(pc,ps,ovstate,sp) 0
-
-#else
-
-// Shorthand for convenience and portability.
-#define OVERLAY(n) __attribute__((overlay(n)))
-
-// Structure of the overlay table required by gdb and the overlay
-// manager. Should not be accessed by user code unless overriding
-// the load process.
-struct ovly_table {
- void * vma; // The overlay's mapped address.
- unsigned int size; // The size of the overlay, in bytes.
- void * lma; // The overlay's load address.
- unsigned int mapped; // Non-zero if overlay is currently mapped; zero otherwise.
-};
-
-// Constructed by the linker. Required for gdb and for the overlay
-// manager. Should not be accessed by user code unless overriding
-// the load process.
-extern struct ovly_table _ovly_table[];
-
-// Functions.
-void xt_overlay_map(int ov_id);
-int xt_overlay_map_async(int ov_id);
-int xt_overlay_map_in_progress(void);
-unsigned int xt_overlay_get_state(unsigned int pc);
-unsigned int xt_overlay_check_map(unsigned int * pc, unsigned int * ps,
- unsigned int ovstate, unsigned int sp);
-int xt_overlay_start_map(void * dst, void * src, unsigned int len, int ov_id);
-int xt_overlay_is_mapping(int ov_id);
-void xt_overlay_fatal_error(int ov_id);
-
-
-// Returns the current overlay ID. If no overlay is mapped or an overlay
-// is in the middle of being mapped, returns -1. Inlined to avoid calling
-// out of overlay (wastes cycles, can end up reading wrong ID on interrupt
-// activity).
-//
-static inline int xt_overlay_get_id(void)
-{
-#pragma always_inline
-extern short _mapping_id;
-extern short _ovly_id;
-
- int ret;
- unsigned int flags = XTOS_SET_INTLEVEL(15);
-
- if (_mapping_id >= 0) {
- ret = -1;
- }
- else {
- ret = _ovly_id;
- }
-
- XTOS_RESTORE_INTLEVEL(flags);
- return ret;
-}
-
-
-// The following macros are used to declare numbered overlays and generate
-// the corresponding call stubs. Use as follows:
-//
-// DECLARE_OVERLAY(n)
-//
-// See documentation for more details.
-
-//#include
-
-// At this time overlays are not supported without windowing.
-#if defined(__XTENSA_WINDOWED_ABI__)
-
-#define xstr(x) str(x)
-#define str(x) #x
-
-// At entry, register a8 holds the return address and a9 holds the target
-// function address. This stub saves a8 on the stack at (SP - 20) which
-// is the only location that is safe for us to use. Then it allocates 32
-// bytes on the stack for working storage, loads the overlay number into
-// a8, and jumps to the common handler. The common handler will make sure
-// that the called function is loaded into memory before calling it.
-// NOTE: we are using the stack area normally reserved for nested functions.
-// This means nested functions cannot be used when overlays are in use.
-
-#define CALL_IN(num) \
- asm(".section .gnu.linkonce.t.overlay.call." xstr(num) ".text, \"ax\"\n" \
- ".global _overlay_call_in_" xstr(num) "_\n" \
- ".align 4\n" \
- "_overlay_call_in_" xstr(num) "_:\n" \
- "s32e a8, a1, -20\n" \
- "addi a8, a1, -32\n" \
- "movsp a1, a8\n" \
- "movi a8, " xstr(num) "\n" \
- "j _overlay_call_in_common\n" \
- ".size _overlay_call_in_" xstr(num) "_, . - _overlay_call_in_" xstr(num) "_\n");
-
-// The call-out stub first calls the target function, then loads the overlay
-// number into register a14 and jumps to the common handler. The handler will
-// make sure that the caller function is present in memory before returning.
-// Note that registers a10-a13 may contain return values so must be preserved.
-//
-// Because we came here via a call4, the return address is in a4, and the top
-// 2 bits are set to the window increment. We'll restore the top 2 bits of
-// the return address from the called function's address, assuming that both
-// are in the same 1 GB segment. For now this is always true.
-
-#define CALL_OUT(num) \
- asm(".section .gnu.linkonce.t.overlay.call." xstr(num) ".text, \"ax\"\n" \
- ".global _overlay_call_out_" xstr(num) "_\n" \
- ".align 4\n" \
- "_overlay_call_out_" xstr(num) "_:\n" \
- "slli a4, a4, 2\n" \
- "srli a4, a4, 2\n" \
- "extui a8, a9, 30, 2\n" \
- "slli a8, a8, 30\n" \
- "or a4, a4, a8\n" \
- "callx8 a9\n" \
- "movi a14, " xstr(num) "\n" \
- "j _overlay_call_out_common\n" \
- ".size _overlay_call_out_" xstr(num) "_, . - _overlay_call_out_" xstr(num) "_\n");
-
-// Generate a call-in and a call-out stub for each overlay.
-
-#define DECLARE_OVERLAY(num) \
- CALL_IN(num) \
- CALL_OUT(num)
-
-#endif // defined(__XTENSA_WINDOWED_ABI__)
-
-#endif // XT_DISABLE_OVERLAYS
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // OVERLAY_H
-
diff --git a/components/esp32/include/xtensa/overlay_os_asm.h b/components/esp32/include/xtensa/overlay_os_asm.h
deleted file mode 100644
index 4adc044e6a..0000000000
--- a/components/esp32/include/xtensa/overlay_os_asm.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// overlay_os_asm.h -- Overlay manager assembly macros for OS use.
-// $Id$
-
-// Copyright (c) 2013 Tensilica Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-#ifndef OVERLAY_OS_ASM_H
-#define OVERLAY_OS_ASM_H
-
-// The macros in here are intended to be used by RTOS task switch code
-// to check overlay status. Such code is usually in assembly and cannot
-// call C code without penalty. For C code usage, it is best to use the
-// corresponding C functions from the library.
-
-
-// Inline assembly version of xt_overlay_get_state(). The arguments are
-// three AR registers (a0-a15):
-//
-// "pcreg" - should contain the outgoing task's PC, i.e. the point at
-// which the task got interrupted. The return value is also
-// returned in this register.
-// "sr1/2" - Scratch registers. These must be distinct from "pcreg".
-//
-// The return value is a 32-bit result that should be saved with the
-// task context and passed as-is to xt_overlay_check_map.
-
- .macro _xt_overlay_get_state pcreg sr1 sr2
-
- movi \sr1, _mapping_id
- movi \sr2, _ovly_id
- l16si \sr1, \sr1, 0
- l16ui \sr2, \sr2, 0
- slli \sr1, \sr1, 16
- or \pcreg, \sr1, \sr2
-
- .endm
-
-
-// Inline assembly version of xt_overlay_check_map(). It requires 5 AR
-// registers (a0-a15) as arguments.
-//
-// "pcreg" - should contain the interrupted task's PC, i.e. the point
-// at which the task got interrupted. This will be adjusted
-// if required.
-// "psreg" - should contain the interrupted task's PS. This will be
-// adjusted if required.
-// "ovreg" - should contain the overlay state on entry. Contents may
-// be clobbered.
-// "spreg" - should contain the tasks stack pointer on entry.
-// "sr1" - Scratch register. Must be distinct from any of the above.
-//
-// The return values are "pcreg" and "psreg" and these must be used
-// to update the task's PC and PS.
-// Note that this macro may store data below the "spreg" pointer. If
-// it does, then it will also disable interrupts via the PS, so that
-// the task resumes with all interrupts disabled (to avoid corrupting
-// this data).
-//
-// (SP - 24) Overlay ID to restore
-// (SP - 28) Task PC
-// (SP - 32) Task PS
-
- .macro _xt_overlay_check_map pcreg psreg ovreg spreg sr1
-
-// There are four cases to deal with:
-//
-// _ovly_id = -1, _mapping_id = -1
-// No overlay is mapped or mapping, nothing to do.
-//
-// _ovly_id >= 0, _mapping_id = -1
-// An overlay was mapped, check PC to see if we need a restore.
-//
-// _ovly_id = -1, _mapping_id >= 0
-// An overlay is being mapped. Either it belongs to this task, which
-// implies that the PC is in the mapping function, or it does not
-// belong to this task. Either way there is nothing to do.
-//
-// _ovly_id >= 0, _mapping_id >= 0
-// Illegal, cannot happen by design. Don't need to handle this.
-//
-// So, the logic is to check _ovly_id first. If this is >= 0, then
-// we check the task PC. If the PC is in the regions of interest then
-// we'll patch the return PC to invoke xt_overlay_restore.
-
-.L1:
- extui \sr1, \ovreg, 0, 16 // Extract _ovly_id
- bbsi.l \sr1, 15, .Lno // If -1 then we're done
- mov \ovreg, \sr1 // Restore this one
-
-// Next check the PC to see if it falls within the ranges of interest.
-
-.L2:
- movi \sr1, _overlay_vma // Is PC < VMA range ?
- bltu \pcreg, \sr1, .L3
- movi \sr1, _overlay_vma_end // Is PC > VMA range ?
- bgeu \pcreg, \sr1, .L3
- j .L4 // PC is in VMA range
-.L3:
- movi \sr1, _overlay_call_stubs_start // Is PC < call stubs range ?
- bltu \pcreg, \sr1, .Lno
- movi \sr1, _overlay_call_stubs_end // Is PC > call stubs range ?
- bgeu \pcreg, \sr1, .Lno
-
-// If we get here then a restore is needed. Save the overlay ID, PC and PS.
-// Return modified PC and PS so that xt_overlay_restore() will execute in
-// the context of the task when resumed. Note that the OS resumption code
-// may expect PS.EXCM to be set so we leave it as is in the return value.
-
-.L4:
- s32e \ovreg, \spreg, -24 // Save overlay ID
- s32e \pcreg, \spreg, -28 // Save task PC
- s32e \psreg, \spreg, -32 // Save task PS
- movi \pcreg, xt_overlay_restore // Adjust resumption PC
- movi \sr1, 15
- or \psreg, \psreg, \sr1 // Set intlevel to highest
-.Lno:
-
- .endm
-
-#endif // OVERLAY_OS_ASM_H
-
diff --git a/components/esp32/include/xtensa/sim.h b/components/esp32/include/xtensa/sim.h
deleted file mode 100644
index e02087c5c0..0000000000
--- a/components/esp32/include/xtensa/sim.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (c) 2004-2006 by Tensilica Inc. ALL RIGHTS RESERVED.
-/ These coded instructions, statements, and computer programs are the
-/ copyrighted works and confidential proprietary information of Tensilica Inc.
-/ They may not be modified, copied, reproduced, distributed, or disclosed to
-/ third parties in any manner, medium, or form, in whole or in part, without
-/ the prior written consent of Tensilica Inc.
-*/
-
-/* sim.h
- *
- * Definitions and prototypes for specific ISS SIMCALLs
- * (ie. outside the standard C library).
- */
-
-#ifndef _INC_SIM_H_
-#define _INC_SIM_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Shortcuts for enabling/disabling profiling in the Xtensa ISS */
-extern void xt_iss_profile_enable(void);
-extern void xt_iss_profile_disable(void);
-
-/* Shortcut for setting the trace level in the Xtensa ISS */
-extern void xt_iss_trace_level(unsigned level);
-
-/* Generic interface for passing client commands in the Xtensa ISS:
- * returns 0 on success, -1 on failure.
- */
-extern int xt_iss_client_command(const char *client, const char *command);
-
-/* Interface for switching simulation modes in the Xtensa ISS:
- * returns 0 on success, -1 on failure.
- */
-#define XT_ISS_CYCLE_ACCURATE 0
-#define XT_ISS_FUNCTIONAL 1
-extern int xt_iss_switch_mode(int mode);
-
-
-/* Interface for waiting on a system synchronization event */
-extern void xt_iss_event_wait(unsigned event_id);
-
-/* Interface for firing a system synchronization event */
-extern void xt_iss_event_fire(unsigned event_id);
-
-/* Interface for invoking a user simcall action,
- * which can be registered in XTMP or XTSC.
- */
-extern int xt_iss_simcall(int arg1, int arg2, int arg3,
- int arg4, int arg5, int arg6);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*_INC_SIM_H_*/
-
diff --git a/components/esp32/include/xtensa/simboard.h b/components/esp32/include/xtensa/simboard.h
deleted file mode 100644
index 980b0b7596..0000000000
--- a/components/esp32/include/xtensa/simboard.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2001 Tensilica Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/* simboard.h - Xtensa ISS "Board" specific definitions */
-
-#ifndef _INC_SIMBOARD_H_
-#define _INC_SIMBOARD_H_
-
-#include
-#include
-
-
-/*
- * Device addresses.
- */
-
-/* System ROM: */
-#define XTBOARD_ROM_SIZE XSHAL_ROM_SIZE
-#ifdef XSHAL_ROM_VADDR
-#define XTBOARD_ROM_VADDR XSHAL_ROM_VADDR
-#endif
-#ifdef XSHAL_ROM_PADDR
-#define XTBOARD_ROM_PADDR XSHAL_ROM_PADDR
-#endif
-
-/* System RAM: */
-#define XTBOARD_RAM_SIZE XSHAL_RAM_SIZE
-#ifdef XSHAL_RAM_VADDR
-#define XTBOARD_RAM_VADDR XSHAL_RAM_VADDR
-#endif
-#ifdef XSHAL_RAM_PADDR
-#define XTBOARD_RAM_PADDR XSHAL_RAM_PADDR
-#endif
-
-
-/*
- * Things that depend on device addresses.
- */
-
-#define XTBOARD_CACHEATTR_WRITEBACK XSHAL_ISS_CACHEATTR_WRITEBACK
-#define XTBOARD_CACHEATTR_WRITEALLOC XSHAL_ISS_CACHEATTR_WRITEALLOC
-#define XTBOARD_CACHEATTR_WRITETHRU XSHAL_ISS_CACHEATTR_WRITETHRU
-#define XTBOARD_CACHEATTR_BYPASS XSHAL_ISS_CACHEATTR_BYPASS
-#define XTBOARD_CACHEATTR_DEFAULT XSHAL_ISS_CACHEATTR_DEFAULT
-
-#define XTBOARD_BUSINT_PIPE_REGIONS 0
-#define XTBOARD_BUSINT_SDRAM_REGIONS 0
-
-
-#endif /*_INC_SIMBOARD_H_*/
-
diff --git a/components/esp32/include/xtensa/simcall-errno.h b/components/esp32/include/xtensa/simcall-errno.h
deleted file mode 100644
index 445ec90135..0000000000
--- a/components/esp32/include/xtensa/simcall-errno.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* Error numbers for Xtensa ISS semihosting. */
-
-/* Copyright (c) 2003 by Tensilica Inc. ALL RIGHTS RESERVED.
- These coded instructions, statements, and computer programs are the
- copyrighted works and confidential proprietary information of Tensilica Inc.
- They may not be modified, copied, reproduced, distributed, or disclosed to
- third parties in any manner, medium, or form, in whole or in part, without
- the prior written consent of Tensilica Inc. */
-
-#ifndef _SIMCALL_ERRNO_H
-#define _SIMCALL_ERRNO_H
-
-/* Define the error numbers (using the default newlib values) with prefixes
- so they can be used in ISS without conflicting with the host values. */
-
-#define _SIMC_EPERM 1
-#define _SIMC_ENOENT 2
-#define _SIMC_ESRCH 3
-#define _SIMC_EINTR 4
-#define _SIMC_EIO 5
-#define _SIMC_ENXIO 6
-#define _SIMC_E2BIG 7
-#define _SIMC_ENOEXEC 8
-#define _SIMC_EBADF 9
-#define _SIMC_ECHILD 10
-#define _SIMC_EAGAIN 11
-#define _SIMC_ENOMEM 12
-#define _SIMC_EACCES 13
-#define _SIMC_EFAULT 14
-#define _SIMC_ENOTBLK 15
-#define _SIMC_EBUSY 16
-#define _SIMC_EEXIST 17
-#define _SIMC_EXDEV 18
-#define _SIMC_ENODEV 19
-#define _SIMC_ENOTDIR 20
-#define _SIMC_EISDIR 21
-#define _SIMC_EINVAL 22
-#define _SIMC_ENFILE 23
-#define _SIMC_EMFILE 24
-#define _SIMC_ENOTTY 25
-#define _SIMC_ETXTBSY 26
-#define _SIMC_EFBIG 27
-#define _SIMC_ENOSPC 28
-#define _SIMC_ESPIPE 29
-#define _SIMC_EROFS 30
-#define _SIMC_EMLINK 31
-#define _SIMC_EPIPE 32
-#define _SIMC_EDOM 33
-#define _SIMC_ERANGE 34
-#define _SIMC_ENOMSG 35
-#define _SIMC_EIDRM 36
-#define _SIMC_ECHRNG 37
-#define _SIMC_EL2NSYNC 38
-#define _SIMC_EL3HLT 39
-#define _SIMC_EL3RST 40
-#define _SIMC_ELNRNG 41
-#define _SIMC_EUNATCH 42
-#define _SIMC_ENOCSI 43
-#define _SIMC_EL2HLT 44
-#define _SIMC_EDEADLK 45
-#define _SIMC_ENOLCK 46
-#define _SIMC_EBADE 50
-#define _SIMC_EBADR 51
-#define _SIMC_EXFULL 52
-#define _SIMC_ENOANO 53
-#define _SIMC_EBADRQC 54
-#define _SIMC_EBADSLT 55
-#define _SIMC_EDEADLOCK 56
-#define _SIMC_EBFONT 57
-#define _SIMC_ENOSTR 60
-#define _SIMC_ENODATA 61
-#define _SIMC_ETIME 62
-#define _SIMC_ENOSR 63
-#define _SIMC_ENONET 64
-#define _SIMC_ENOPKG 65
-#define _SIMC_EREMOTE 66
-#define _SIMC_ENOLINK 67
-#define _SIMC_EADV 68
-#define _SIMC_ESRMNT 69
-#define _SIMC_ECOMM 70
-#define _SIMC_EPROTO 71
-#define _SIMC_EMULTIHOP 74
-#define _SIMC_ELBIN 75
-#define _SIMC_EDOTDOT 76
-#define _SIMC_EBADMSG 77
-#define _SIMC_EFTYPE 79
-#define _SIMC_ENOTUNIQ 80
-#define _SIMC_EBADFD 81
-#define _SIMC_EREMCHG 82
-#define _SIMC_ELIBACC 83
-#define _SIMC_ELIBBAD 84
-#define _SIMC_ELIBSCN 85
-#define _SIMC_ELIBMAX 86
-#define _SIMC_ELIBEXEC 87
-#define _SIMC_ENOSYS 88
-#define _SIMC_ENMFILE 89
-#define _SIMC_ENOTEMPTY 90
-#define _SIMC_ENAMETOOLONG 91
-#define _SIMC_ELOOP 92
-#define _SIMC_EOPNOTSUPP 95
-#define _SIMC_EPFNOSUPPORT 96
-#define _SIMC_ECONNRESET 104
-#define _SIMC_ENOBUFS 105
-#define _SIMC_EAFNOSUPPORT 106
-#define _SIMC_EPROTOTYPE 107
-#define _SIMC_ENOTSOCK 108
-#define _SIMC_ENOPROTOOPT 109
-#define _SIMC_ESHUTDOWN 110
-#define _SIMC_ECONNREFUSED 111
-#define _SIMC_EADDRINUSE 112
-#define _SIMC_ECONNABORTED 113
-#define _SIMC_ENETUNREACH 114
-#define _SIMC_ENETDOWN 115
-#define _SIMC_ETIMEDOUT 116
-#define _SIMC_EHOSTDOWN 117
-#define _SIMC_EHOSTUNREACH 118
-#define _SIMC_EINPROGRESS 119
-#define _SIMC_EALREADY 120
-#define _SIMC_EDESTADDRREQ 121
-#define _SIMC_EMSGSIZE 122
-#define _SIMC_EPROTONOSUPPORT 123
-#define _SIMC_ESOCKTNOSUPPORT 124
-#define _SIMC_EADDRNOTAVAIL 125
-#define _SIMC_ENETRESET 126
-#define _SIMC_EISCONN 127
-#define _SIMC_ENOTCONN 128
-#define _SIMC_ETOOMANYREFS 129
-#define _SIMC_EPROCLIM 130
-#define _SIMC_EUSERS 131
-#define _SIMC_EDQUOT 132
-#define _SIMC_ESTALE 133
-#define _SIMC_ENOTSUP 134
-#define _SIMC_ENOMEDIUM 135
-#define _SIMC_ENOSHARE 136
-#define _SIMC_ECASECLASH 137
-#define _SIMC_EILSEQ 138
-#define _SIMC_EOVERFLOW 139
-
-#endif /* ! _SIMCALL_ERRNO_H */
diff --git a/components/esp32/include/xtensa/simcall-fcntl.h b/components/esp32/include/xtensa/simcall-fcntl.h
deleted file mode 100644
index 1c03f5595e..0000000000
--- a/components/esp32/include/xtensa/simcall-fcntl.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* File control operations for Xtensa ISS semihosting. */
-
-/* Copyright (c) 2003 by Tensilica Inc. ALL RIGHTS RESERVED.
- These coded instructions, statements, and computer programs are the
- copyrighted works and confidential proprietary information of Tensilica Inc.
- They may not be modified, copied, reproduced, distributed, or disclosed to
- third parties in any manner, medium, or form, in whole or in part, without
- the prior written consent of Tensilica Inc. */
-
-#ifndef _SIMCALL_FCNTL_H
-#define _SIMCALL_FCNTL_H
-
-#define _SIMC_O_APPEND 0x0008
-#define _SIMC_O_NONBLOCK 0x0080
-#define _SIMC_O_CREAT 0x0100
-#define _SIMC_O_TRUNC 0x0200
-#define _SIMC_O_EXCL 0x0400
-#define _SIMC_O_TEXT 0x4000
-#define _SIMC_O_BINARY 0x8000
-
-#endif /* ! _SIMCALL_FCNTL_H */
diff --git a/components/esp32/include/xtensa/simcall.h b/components/esp32/include/xtensa/simcall.h
deleted file mode 100644
index d71959eea7..0000000000
--- a/components/esp32/include/xtensa/simcall.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * simcall.h - Simulator call numbers
- *
- * Software that runs on a simulated Xtensa processor using
- * the instruction set simulator (ISS) can invoke simulator
- * services using the SIMCALL instruction. The a2 register
- * is set prior to executing SIMCALL to a "simcall number",
- * indicating which service to invoke. This file defines the
- * simcall numbers defined and/or supported by the Xtensa ISS.
- *
- * IMPORTANT NOTE: These numbers are highly subject to change!
- *
- * Copyright (c) 2002-2007 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-#ifndef SIMCALL_INCLUDED
-#define SIMCALL_INCLUDED
-
-/*
- * System call like services offered by the simulator host.
- * These are modeled after the Linux 2.4 kernel system calls
- * for Xtensa processors. However not all system calls and
- * not all functionality of a given system call are implemented,
- * or necessarily have well defined or equivalent semantics in
- * the context of a simulation (as opposed to a Unix kernel).
- *
- * These services behave largely as if they had been invoked
- * as a task in the simulator host's operating system
- * (eg. files accessed are those of the simulator host).
- * However, these SIMCALLs model a virtual operating system
- * so that various definitions, bit assignments etc
- * (eg. open mode bits, errno values, etc) are independent
- * of the host operating system used to run the simulation.
- * Rather these definitions are specific to the Xtensa ISS.
- * This way Xtensa ISA code written to use these SIMCALLs
- * can (in principle) be simulated on any host.
- *
- * Up to 6 parameters are passed in registers a3 to a8
- * (note the 6th parameter isn't passed on the stack,
- * unlike windowed function calling conventions).
- * The return value is in a2. A negative value in the
- * range -4096 to -1 indicates a negated error code to be
- * reported in errno with a return value of -1, otherwise
- * the value in a2 is returned as is.
- */
-
-/* These #defines need to match what's in Xtensa/OS/vxworks/xtiss/simcalls.c */
-
-#define SYS_nop 0 /* n/a - setup; used to flush register windows */
-#define SYS_exit 1 /*x*/
-#define SYS_fork 2
-#define SYS_read 3 /*x*/
-#define SYS_write 4 /*x*/
-#define SYS_open 5 /*x*/
-#define SYS_close 6 /*x*/
-#define SYS_rename 7 /*x 38 - waitpid */
-#define SYS_creat 8 /*x*/
-#define SYS_link 9 /*x (not implemented on WIN32) */
-#define SYS_unlink 10 /*x*/
-#define SYS_execv 11 /* n/a - execve */
-#define SYS_execve 12 /* 11 - chdir */
-#define SYS_pipe 13 /* 42 - time */
-#define SYS_stat 14 /* 106 - mknod */
-#define SYS_chmod 15
-#define SYS_chown 16 /* 202 - lchown */
-#define SYS_utime 17 /* 30 - break */
-#define SYS_wait 18 /* n/a - oldstat */
-#define SYS_lseek 19 /*x*/
-#define SYS_getpid 20
-#define SYS_isatty 21 /* n/a - mount */
-#define SYS_fstat 22 /* 108 - oldumount */
-#define SYS_time 23 /* 13 - setuid */
-#define SYS_gettimeofday 24 /*x 78 - getuid (not implemented on WIN32) */
-#define SYS_times 25 /*X 43 - stime (Xtensa-specific implementation) */
-#define SYS_socket 26
-#define SYS_sendto 27
-#define SYS_recvfrom 28
-#define SYS_select_one 29 /* not compitible select, one file descriptor at the time */
-#define SYS_bind 30
-#define SYS_ioctl 31
-
-/*
- * Other...
- */
-#define SYS_iss_argc 1000 /* returns value of argc */
-#define SYS_iss_argv_size 1001 /* bytes needed for argv & arg strings */
-#define SYS_iss_set_argv 1002 /* saves argv & arg strings at given addr */
-
-#define SYS_memset 1004 /* fill a range of memory (fast) */
-
-/*
- * SIMCALLs for the ferret memory debugger. All are invoked by
- * libferret.a ... ( Xtensa/Target-Libs/ferret )
- */
-#define SYS_ferret 1010
-#define SYS_malloc 1011
-#define SYS_free 1012
-#define SYS_more_heap 1013
-#define SYS_no_heap 1014
-#define SYS_enter_ferret 1015
-#define SYS_leave_ferret 1016
-
-/*
- * SIMCALLs for ISS client commands
- */
-#define SYS_profile_enable 1020
-#define SYS_profile_disable 1021
-#define SYS_trace_level 1022
-#define SYS_client_command 1023
-
-/*
- * SIMCALL for simulation mode switching
- */
-#define SYS_sim_mode_switch 1030
-
-/*
- * SIMCALLs for XTMP/XTSC event notify and core stall
- */
-#define SYS_event_fire 1040
-#define SYS_event_stall 1041
-
-/*
- * SIMCALLs for callbacks registered in XTMP/XTSC
- */
-#define SYS_callback_first 100
-#define SYS_callback_last 999
-
-/*
- * User defined simcall
- */
-#define SYS_user_simcall 100
-
-#define SYS_xmpa_errinfo 200
-#define SYS_xmpa_proc_status 201
-#define SYS_xmpa_proc_start 202
-#define SYS_xmpa_proc_stop 203
-#define SYS_xmpa_proc_mem_read 204
-#define SYS_xmpa_proc_mem_write 205
-#define SYS_xmpa_proc_mem_fill 206
-#define SYS_xmpa_proc_reg_read 207
-#define SYS_xmpa_proc_reg_write 208
-
-
-/*
- * Extra SIMCALLs for GDB:
- */
-#define SYS_gdb_break -1 /* invoked by XTOS on user exceptions if EPC points
- to a break.n/break, regardless of cause! */
-#define SYS_xmon_out -2 /* invoked by XMON: ... */
-#define SYS_xmon_in -3 /* invoked by XMON: ... */
-#define SYS_xmon_flush -4 /* invoked by XMON: ... */
-#define SYS_gdb_abort -5 /* invoked by XTOS in _xtos_panic() */
-#define SYS_gdb_illegal_inst -6 /* invoked by XTOS for illegal instructions (too deeply) */
-#define SYS_xmon_init -7 /* invoked by XMON: ... */
-#define SYS_gdb_enter_sktloop -8 /* invoked by XTOS on debug exceptions */
-#define SYS_unhandled_kernel_exc -9 /* invoked by XTOS for unhandled kernel exceptions */
-#define SYS_unhandled_user_exc -10 /* invoked by XTOS for unhandled user exceptions */
-#define SYS_unhandled_double_exc -11 /* invoked by XTOS for unhandled double exceptions */
-#define SYS_unhandled_highpri_interrupt -12 /* invoked by XTOS for unhandled high-priority interrupts */
-#define SYS_xmon_close -13 /* invoked by XMON: ... */
-
-/*
- * SIMCALLs for vxWorks xtiss BSP:
- */
-#define SYS_setup_ppp_pipes -83
-#define SYS_log_msg -84
-
-/*
- * SYS_select_one specifiers
- */
-#define XTISS_SELECT_ONE_READ 1
-#define XTISS_SELECT_ONE_WRITE 2
-#define XTISS_SELECT_ONE_EXCEPT 3
-
-/*
- * SIMCALL for client calling arbitrary code in a client plug in.
- * see clients/xcc_instr to see how this works.
- */
-
-#define SYS_client 0xC0DECAFE
-
-
-
-#endif /* !SIMCALL_INCLUDED */
diff --git a/components/esp32/include/xtensa/tie/xt_DFP_assist.h b/components/esp32/include/xtensa/tie/xt_DFP_assist.h
deleted file mode 100644
index 4d529ebd3f..0000000000
--- a/components/esp32/include/xtensa/tie/xt_DFP_assist.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Definitions for the xt_DFP_assist TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_DFP_assist_HEADER
-#define _XTENSA_xt_DFP_assist_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern void _TIE_xt_DFP_assist_F64ITER(unsigned arr /*inout*/, unsigned ars, unsigned art, immediate oper, immediate noshift);
-extern unsigned _TIE_xt_DFP_assist_F64RND(unsigned ars, unsigned art, immediate mode);
-extern void _TIE_xt_DFP_assist_F64ADDC(unsigned art /*inout*/, unsigned ars, immediate immZ, immediate immC);
-extern void _TIE_xt_DFP_assist_F64SUBC(unsigned art /*inout*/, unsigned ars, immediate immZ, immediate immC);
-extern unsigned _TIE_xt_DFP_assist_F64SIG(unsigned ars);
-extern unsigned _TIE_xt_DFP_assist_F64CMPL(unsigned ars, unsigned art);
-extern unsigned _TIE_xt_DFP_assist_F64CMPH(unsigned ars, unsigned art, immediate oper);
-extern unsigned _TIE_xt_DFP_assist_F64NORM(unsigned ars, unsigned art, immediate mode);
-extern unsigned _TIE_xt_DFP_assist_F64SEXP(unsigned ars, unsigned art);
-extern unsigned _TIE_xt_DFP_assist_RF64R(immediate hilo);
-extern void _TIE_xt_DFP_assist_WF64R(unsigned ars, unsigned art, immediate hilo);
-extern unsigned _TIE_xt_DFP_assist_RUR_F64R_LO(void);
-extern unsigned _TIE_xt_DFP_assist_RUR_F64R_HI(void);
-extern void _TIE_xt_DFP_assist_WUR_F64R_LO(unsigned art);
-extern void _TIE_xt_DFP_assist_WUR_F64R_HI(unsigned art);
-extern unsigned _TIE_xt_DFP_assist_RUR_F64S(void);
-extern void _TIE_xt_DFP_assist_WUR_F64S(unsigned art);
-#define F64ITER _TIE_xt_DFP_assist_F64ITER
-#define F64RND _TIE_xt_DFP_assist_F64RND
-#define F64ADDC _TIE_xt_DFP_assist_F64ADDC
-#define F64SUBC _TIE_xt_DFP_assist_F64SUBC
-#define F64SIG _TIE_xt_DFP_assist_F64SIG
-#define F64CMPL _TIE_xt_DFP_assist_F64CMPL
-#define F64CMPH _TIE_xt_DFP_assist_F64CMPH
-#define F64NORM _TIE_xt_DFP_assist_F64NORM
-#define F64SEXP _TIE_xt_DFP_assist_F64SEXP
-#define RF64R _TIE_xt_DFP_assist_RF64R
-#define WF64R _TIE_xt_DFP_assist_WF64R
-#define RUR_F64R_LO _TIE_xt_DFP_assist_RUR_F64R_LO
-#define RF64R_LO _TIE_xt_DFP_assist_RUR_F64R_LO
-#define RUR234 _TIE_xt_DFP_assist_RUR_F64R_LO
-#define RUR_F64R_HI _TIE_xt_DFP_assist_RUR_F64R_HI
-#define RF64R_HI _TIE_xt_DFP_assist_RUR_F64R_HI
-#define RUR235 _TIE_xt_DFP_assist_RUR_F64R_HI
-#define WUR_F64R_LO _TIE_xt_DFP_assist_WUR_F64R_LO
-#define WF64R_LO _TIE_xt_DFP_assist_WUR_F64R_LO
-#define WUR234 _TIE_xt_DFP_assist_WUR_F64R_LO
-#define WUR_F64R_HI _TIE_xt_DFP_assist_WUR_F64R_HI
-#define WF64R_HI _TIE_xt_DFP_assist_WUR_F64R_HI
-#define WUR235 _TIE_xt_DFP_assist_WUR_F64R_HI
-#define RUR_F64S _TIE_xt_DFP_assist_RUR_F64S
-#define RF64S _TIE_xt_DFP_assist_RUR_F64S
-#define RUR236 _TIE_xt_DFP_assist_RUR_F64S
-#define WUR_F64S _TIE_xt_DFP_assist_WUR_F64S
-#define WF64S _TIE_xt_DFP_assist_WUR_F64S
-#define WUR236 _TIE_xt_DFP_assist_WUR_F64S
-
-#ifndef RUR
-#define RUR(NUM) RUR##NUM()
-#endif
-
-#ifndef WUR
-#define WUR(VAL, NUM) WUR##NUM(VAL)
-#endif
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_DFP_assist_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_FP.h b/components/esp32/include/xtensa/tie/xt_FP.h
deleted file mode 100644
index 229a108ab7..0000000000
--- a/components/esp32/include/xtensa/tie/xt_FP.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/* Definitions for the xt_FP TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_FP_HEADER
-#define _XTENSA_xt_FP_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-#include
-typedef float _TIE_xt_FP_xtfloat;
-typedef _TIE_xt_FP_xtfloat xtfloat;
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern unsigned _TIE_xt_FP_RUR_FCR(void);
-extern void _TIE_xt_FP_WUR_FCR(unsigned v);
-extern unsigned _TIE_xt_FP_RUR_FSR(void);
-extern void _TIE_xt_FP_WUR_FSR(unsigned v);
-extern xtfloat _TIE_xt_FP_xtfloat_loadi(const xtfloat * p, immediate imm8x4);
-extern void _TIE_xt_FP_xtfloat_storei(xtfloat t, xtfloat * p, immediate imm8x4);
-extern void _TIE_xt_FP_xtfloat_loadip(xtfloat t /*out*/, const xtfloat * p /*inout*/, immediate imm8x4);
-extern void _TIE_xt_FP_xtfloat_storeip(xtfloat t, xtfloat * p /*inout*/, immediate imm8x4);
-extern xtfloat _TIE_xt_FP_xtfloat_loadx(const xtfloat * p, int imm8x4);
-extern void _TIE_xt_FP_xtfloat_storex(xtfloat t, xtfloat * p, int imm8x4);
-extern void _TIE_xt_FP_xtfloat_loadxp(xtfloat t /*out*/, const xtfloat * p /*inout*/, int imm8x4);
-extern void _TIE_xt_FP_xtfloat_storexp(xtfloat t, xtfloat * p /*inout*/, int imm8x4);
-extern xtfloat _TIE_xt_FP_xtfloat_move(xtfloat r);
-extern int _TIE_xt_FP_ROUND_S(xtfloat s, immediate t);
-extern int _TIE_xt_FP_TRUNC_S(xtfloat s, immediate t);
-extern unsigned _TIE_xt_FP_UTRUNC_S(xtfloat s, immediate t);
-extern int _TIE_xt_FP_FLOOR_S(xtfloat s, immediate t);
-extern int _TIE_xt_FP_CEIL_S(xtfloat s, immediate t);
-extern xtfloat _TIE_xt_FP_LSI(const xtfloat * p, immediate imm8x4);
-extern void _TIE_xt_FP_SSI(xtfloat t, xtfloat * p, immediate imm8x4);
-extern void _TIE_xt_FP_LSIP(xtfloat t /*out*/, const xtfloat * p /*inout*/, immediate imm8x4);
-extern void _TIE_xt_FP_SSIP(xtfloat t, xtfloat * p /*inout*/, immediate imm8x4);
-extern xtfloat _TIE_xt_FP_LSX(const xtfloat * p, int imm8x4);
-extern void _TIE_xt_FP_SSX(xtfloat t, xtfloat * p, int imm8x4);
-extern void _TIE_xt_FP_LSXP(xtfloat t /*out*/, const xtfloat * p /*inout*/, int imm8x4);
-extern void _TIE_xt_FP_SSXP(xtfloat t, xtfloat * p /*inout*/, int imm8x4);
-extern xtfloat _TIE_xt_FP_ABS_S(xtfloat s);
-extern xtfloat _TIE_xt_FP_NEG_S(xtfloat s);
-extern xtfloat _TIE_xt_FP_MOV_S(xtfloat s);
-extern void _TIE_xt_FP_MOVEQZ_S(xtfloat r /*inout*/, xtfloat s, int t);
-extern void _TIE_xt_FP_MOVNEZ_S(xtfloat r /*inout*/, xtfloat s, int t);
-extern void _TIE_xt_FP_MOVLTZ_S(xtfloat r /*inout*/, xtfloat s, int t);
-extern void _TIE_xt_FP_MOVGEZ_S(xtfloat r /*inout*/, xtfloat s, int t);
-extern void _TIE_xt_FP_MOVF_S(xtfloat r /*inout*/, xtfloat s, xtbool t);
-extern void _TIE_xt_FP_MOVT_S(xtfloat r /*inout*/, xtfloat s, xtbool t);
-extern unsigned _TIE_xt_FP_RFR(xtfloat s);
-extern xtfloat _TIE_xt_FP_WFR(unsigned s);
-extern xtfloat _TIE_xt_FP_FLOAT_S(int s, immediate t);
-extern xtfloat _TIE_xt_FP_UFLOAT_S(unsigned s, immediate t);
-extern xtbool _TIE_xt_FP_OEQ_S(xtfloat s, xtfloat t);
-extern xtbool _TIE_xt_FP_OLE_S(xtfloat s, xtfloat t);
-extern xtbool _TIE_xt_FP_OLT_S(xtfloat s, xtfloat t);
-extern xtbool _TIE_xt_FP_UEQ_S(xtfloat s, xtfloat t);
-extern xtbool _TIE_xt_FP_ULE_S(xtfloat s, xtfloat t);
-extern xtbool _TIE_xt_FP_ULT_S(xtfloat s, xtfloat t);
-extern xtbool _TIE_xt_FP_UN_S(xtfloat s, xtfloat t);
-extern xtfloat _TIE_xt_FP_ADD_S(xtfloat s, xtfloat t);
-extern xtfloat _TIE_xt_FP_SUB_S(xtfloat s, xtfloat t);
-extern xtfloat _TIE_xt_FP_MUL_S(xtfloat s, xtfloat t);
-extern void _TIE_xt_FP_MADD_S(xtfloat r /*inout*/, xtfloat s, xtfloat t);
-extern void _TIE_xt_FP_MSUB_S(xtfloat r /*inout*/, xtfloat s, xtfloat t);
-extern xtfloat _TIE_xt_FP_RECIP0_S(xtfloat s);
-extern xtfloat _TIE_xt_FP_DIV0_S(xtfloat s);
-extern xtfloat _TIE_xt_FP_NEXP01_S(xtfloat s);
-extern xtfloat _TIE_xt_FP_CONST_S(immediate s);
-extern void _TIE_xt_FP_MKDADJ_S(xtfloat r /*inout*/, xtfloat s);
-extern xtfloat _TIE_xt_FP_MKSADJ_S(xtfloat s);
-extern void _TIE_xt_FP_ADDEXPM_S(xtfloat r /*inout*/, xtfloat s);
-extern void _TIE_xt_FP_ADDEXP_S(xtfloat r /*inout*/, xtfloat s);
-extern void _TIE_xt_FP_DIVN_S(xtfloat r /*inout*/, xtfloat s, xtfloat t);
-extern xtfloat _TIE_xt_FP_RSQRT0_S(xtfloat s);
-extern xtfloat _TIE_xt_FP_SQRT0_S(xtfloat s);
-extern void _TIE_xt_FP_MADDN_S(xtfloat r /*inout*/, xtfloat s, xtfloat t);
-extern xtfloat _TIE_xt_FP_DIV_S(xtfloat s, xtfloat t);
-extern xtfloat _TIE_xt_FP_SQRT_S(xtfloat s);
-extern xtfloat _TIE_xt_FP_RECIP_S(xtfloat s);
-extern xtfloat _TIE_xt_FP_RSQRT_S(xtfloat s);
-extern xtfloat _TIE_xt_FP_FSQRT_S(xtfloat s);
-#define XT_RUR_FCR _TIE_xt_FP_RUR_FCR
-#define RFCR _TIE_xt_FP_RUR_FCR
-#define RUR232 _TIE_xt_FP_RUR_FCR
-#define XT_WUR_FCR _TIE_xt_FP_WUR_FCR
-#define WFCR _TIE_xt_FP_WUR_FCR
-#define WUR232 _TIE_xt_FP_WUR_FCR
-#define XT_RUR_FSR _TIE_xt_FP_RUR_FSR
-#define RFSR _TIE_xt_FP_RUR_FSR
-#define RUR233 _TIE_xt_FP_RUR_FSR
-#define XT_WUR_FSR _TIE_xt_FP_WUR_FSR
-#define WFSR _TIE_xt_FP_WUR_FSR
-#define WUR233 _TIE_xt_FP_WUR_FSR
-#define XT_xtfloat_loadi _TIE_xt_FP_xtfloat_loadi
-#define XT_xtfloat_storei _TIE_xt_FP_xtfloat_storei
-#define XT_xtfloat_loadip _TIE_xt_FP_xtfloat_loadip
-#define XT_xtfloat_storeip _TIE_xt_FP_xtfloat_storeip
-#define XT_xtfloat_loadx _TIE_xt_FP_xtfloat_loadx
-#define XT_xtfloat_storex _TIE_xt_FP_xtfloat_storex
-#define XT_xtfloat_loadxp _TIE_xt_FP_xtfloat_loadxp
-#define XT_xtfloat_storexp _TIE_xt_FP_xtfloat_storexp
-#define XT_xtfloat_move _TIE_xt_FP_xtfloat_move
-#define XT_ROUND_S _TIE_xt_FP_ROUND_S
-#define XT_TRUNC_S _TIE_xt_FP_TRUNC_S
-#define XT_UTRUNC_S _TIE_xt_FP_UTRUNC_S
-#define XT_FLOOR_S _TIE_xt_FP_FLOOR_S
-#define XT_CEIL_S _TIE_xt_FP_CEIL_S
-#define XT_LSI _TIE_xt_FP_LSI
-#define XT_SSI _TIE_xt_FP_SSI
-#define XT_LSIP _TIE_xt_FP_LSIP
-#define XT_SSIP _TIE_xt_FP_SSIP
-#define XT_LSX _TIE_xt_FP_LSX
-#define XT_SSX _TIE_xt_FP_SSX
-#define XT_LSXP _TIE_xt_FP_LSXP
-#define XT_SSXP _TIE_xt_FP_SSXP
-#define XT_ABS_S _TIE_xt_FP_ABS_S
-#define XT_NEG_S _TIE_xt_FP_NEG_S
-#define XT_MOV_S _TIE_xt_FP_MOV_S
-#define XT_MOVEQZ_S _TIE_xt_FP_MOVEQZ_S
-#define XT_MOVNEZ_S _TIE_xt_FP_MOVNEZ_S
-#define XT_MOVLTZ_S _TIE_xt_FP_MOVLTZ_S
-#define XT_MOVGEZ_S _TIE_xt_FP_MOVGEZ_S
-#define XT_MOVF_S _TIE_xt_FP_MOVF_S
-#define XT_MOVT_S _TIE_xt_FP_MOVT_S
-#define XT_RFR _TIE_xt_FP_RFR
-#define XT_WFR _TIE_xt_FP_WFR
-#define XT_FLOAT_S _TIE_xt_FP_FLOAT_S
-#define XT_UFLOAT_S _TIE_xt_FP_UFLOAT_S
-#define XT_OEQ_S _TIE_xt_FP_OEQ_S
-#define XT_OLE_S _TIE_xt_FP_OLE_S
-#define XT_OLT_S _TIE_xt_FP_OLT_S
-#define XT_UEQ_S _TIE_xt_FP_UEQ_S
-#define XT_ULE_S _TIE_xt_FP_ULE_S
-#define XT_ULT_S _TIE_xt_FP_ULT_S
-#define XT_UN_S _TIE_xt_FP_UN_S
-#define XT_ADD_S _TIE_xt_FP_ADD_S
-#define XT_SUB_S _TIE_xt_FP_SUB_S
-#define XT_MUL_S _TIE_xt_FP_MUL_S
-#define XT_MADD_S _TIE_xt_FP_MADD_S
-#define XT_MSUB_S _TIE_xt_FP_MSUB_S
-#define XT_RECIP0_S _TIE_xt_FP_RECIP0_S
-#define XT_DIV0_S _TIE_xt_FP_DIV0_S
-#define XT_NEXP01_S _TIE_xt_FP_NEXP01_S
-#define XT_CONST_S _TIE_xt_FP_CONST_S
-#define XT_MKDADJ_S _TIE_xt_FP_MKDADJ_S
-#define XT_MKSADJ_S _TIE_xt_FP_MKSADJ_S
-#define XT_ADDEXPM_S _TIE_xt_FP_ADDEXPM_S
-#define XT_ADDEXP_S _TIE_xt_FP_ADDEXP_S
-#define XT_DIVN_S _TIE_xt_FP_DIVN_S
-#define XT_RSQRT0_S _TIE_xt_FP_RSQRT0_S
-#define XT_SQRT0_S _TIE_xt_FP_SQRT0_S
-#define XT_MADDN_S _TIE_xt_FP_MADDN_S
-#define XT_DIV_S _TIE_xt_FP_DIV_S
-#define XT_SQRT_S _TIE_xt_FP_SQRT_S
-#define XT_RECIP_S _TIE_xt_FP_RECIP_S
-#define XT_RSQRT_S _TIE_xt_FP_RSQRT_S
-#define XT_FSQRT_S _TIE_xt_FP_FSQRT_S
-
-#ifndef RUR
-#define RUR(NUM) RUR##NUM()
-#endif
-
-#ifndef WUR
-#define WUR(VAL, NUM) WUR##NUM(VAL)
-#endif
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_FP_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_MAC16.h b/components/esp32/include/xtensa/tie/xt_MAC16.h
deleted file mode 100644
index b46a1db7f7..0000000000
--- a/components/esp32/include/xtensa/tie/xt_MAC16.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* Definitions for the xt_MAC16 TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_MAC16_HEADER
-#define _XTENSA_xt_MAC16_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern void _TIE_xt_MAC16_UMUL_AA_HH(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_UMUL_AA_LH(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_UMUL_AA_HL(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_UMUL_AA_LL(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MUL_AA_HH(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MUL_AA_LH(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MUL_AA_HL(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MUL_AA_LL(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MUL_AD_HH(unsigned ars, immediate my);
-extern void _TIE_xt_MAC16_MUL_AD_LH(unsigned ars, immediate my);
-extern void _TIE_xt_MAC16_MUL_AD_HL(unsigned ars, immediate my);
-extern void _TIE_xt_MAC16_MUL_AD_LL(unsigned ars, immediate my);
-extern void _TIE_xt_MAC16_MUL_DA_HH(immediate mx, unsigned art);
-extern void _TIE_xt_MAC16_MUL_DA_LH(immediate mx, unsigned art);
-extern void _TIE_xt_MAC16_MUL_DA_HL(immediate mx, unsigned art);
-extern void _TIE_xt_MAC16_MUL_DA_LL(immediate mx, unsigned art);
-extern void _TIE_xt_MAC16_MUL_DD_HH(immediate mx, immediate my);
-extern void _TIE_xt_MAC16_MUL_DD_LH(immediate mx, immediate my);
-extern void _TIE_xt_MAC16_MUL_DD_HL(immediate mx, immediate my);
-extern void _TIE_xt_MAC16_MUL_DD_LL(immediate mx, immediate my);
-extern void _TIE_xt_MAC16_MULS_AA_HH(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MULS_AA_LH(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MULS_AA_HL(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MULS_AA_LL(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MULA_AA_HH(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MULA_AA_LH(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MULA_AA_HL(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MULA_AA_LL(unsigned ars, unsigned art);
-extern void _TIE_xt_MAC16_MULS_AD_HH(unsigned ars, immediate my);
-extern void _TIE_xt_MAC16_MULS_AD_LH(unsigned ars, immediate my);
-extern void _TIE_xt_MAC16_MULS_AD_HL(unsigned ars, immediate my);
-extern void _TIE_xt_MAC16_MULS_AD_LL(unsigned ars, immediate my);
-extern void _TIE_xt_MAC16_MULA_AD_HH(unsigned ars, immediate my);
-extern void _TIE_xt_MAC16_MULA_AD_LH(unsigned ars, immediate my);
-extern void _TIE_xt_MAC16_MULA_AD_HL(unsigned ars, immediate my);
-extern void _TIE_xt_MAC16_MULA_AD_LL(unsigned ars, immediate my);
-extern void _TIE_xt_MAC16_MULS_DA_HH(immediate mx, unsigned art);
-extern void _TIE_xt_MAC16_MULS_DA_LH(immediate mx, unsigned art);
-extern void _TIE_xt_MAC16_MULS_DA_HL(immediate mx, unsigned art);
-extern void _TIE_xt_MAC16_MULS_DA_LL(immediate mx, unsigned art);
-extern void _TIE_xt_MAC16_MULA_DA_HH(immediate mx, unsigned art);
-extern void _TIE_xt_MAC16_MULA_DA_LH(immediate mx, unsigned art);
-extern void _TIE_xt_MAC16_MULA_DA_HL(immediate mx, unsigned art);
-extern void _TIE_xt_MAC16_MULA_DA_LL(immediate mx, unsigned art);
-extern void _TIE_xt_MAC16_MULS_DD_HH(immediate mx, immediate my);
-extern void _TIE_xt_MAC16_MULS_DD_LH(immediate mx, immediate my);
-extern void _TIE_xt_MAC16_MULS_DD_HL(immediate mx, immediate my);
-extern void _TIE_xt_MAC16_MULS_DD_LL(immediate mx, immediate my);
-extern void _TIE_xt_MAC16_MULA_DD_HH(immediate mx, immediate my);
-extern void _TIE_xt_MAC16_MULA_DD_LH(immediate mx, immediate my);
-extern void _TIE_xt_MAC16_MULA_DD_HL(immediate mx, immediate my);
-extern void _TIE_xt_MAC16_MULA_DD_LL(immediate mx, immediate my);
-extern unsigned _TIE_xt_MAC16_RSR_M0(void);
-extern void _TIE_xt_MAC16_WSR_M0(unsigned art);
-extern void _TIE_xt_MAC16_XSR_M0(unsigned art /*inout*/);
-extern unsigned _TIE_xt_MAC16_RSR_M1(void);
-extern void _TIE_xt_MAC16_WSR_M1(unsigned art);
-extern void _TIE_xt_MAC16_XSR_M1(unsigned art /*inout*/);
-extern unsigned _TIE_xt_MAC16_RSR_M2(void);
-extern void _TIE_xt_MAC16_WSR_M2(unsigned art);
-extern void _TIE_xt_MAC16_XSR_M2(unsigned art /*inout*/);
-extern unsigned _TIE_xt_MAC16_RSR_M3(void);
-extern void _TIE_xt_MAC16_WSR_M3(unsigned art);
-extern void _TIE_xt_MAC16_XSR_M3(unsigned art /*inout*/);
-extern unsigned _TIE_xt_MAC16_RSR_ACCLO(void);
-extern void _TIE_xt_MAC16_WSR_ACCLO(unsigned art);
-extern void _TIE_xt_MAC16_XSR_ACCLO(unsigned art /*inout*/);
-extern unsigned _TIE_xt_MAC16_RSR_ACCHI(void);
-extern void _TIE_xt_MAC16_WSR_ACCHI(unsigned art);
-extern void _TIE_xt_MAC16_XSR_ACCHI(unsigned art /*inout*/);
-extern void _TIE_xt_MAC16_MULA_DA_LL_LDDEC(immediate w, const short * s /*inout*/, immediate x, int t);
-extern void _TIE_xt_MAC16_MULA_DA_LL_LDINC(immediate w, const short * s /*inout*/, immediate x, int t);
-extern void _TIE_xt_MAC16_MULA_DA_HL_LDDEC(immediate w, const short * s /*inout*/, immediate x, int t);
-extern void _TIE_xt_MAC16_MULA_DA_HL_LDINC(immediate w, const short * s /*inout*/, immediate x, int t);
-extern void _TIE_xt_MAC16_MULA_DA_LH_LDDEC(immediate w, const short * s /*inout*/, immediate x, int t);
-extern void _TIE_xt_MAC16_MULA_DA_LH_LDINC(immediate w, const short * s /*inout*/, immediate x, int t);
-extern void _TIE_xt_MAC16_MULA_DA_HH_LDDEC(immediate w, const short * s /*inout*/, immediate x, int t);
-extern void _TIE_xt_MAC16_MULA_DA_HH_LDINC(immediate w, const short * s /*inout*/, immediate x, int t);
-extern void _TIE_xt_MAC16_MULA_DD_LL_LDDEC(immediate w, const short * s /*inout*/, immediate x, immediate y);
-extern void _TIE_xt_MAC16_MULA_DD_LL_LDINC(immediate w, const short * s /*inout*/, immediate x, immediate y);
-extern void _TIE_xt_MAC16_MULA_DD_HL_LDDEC(immediate w, const short * s /*inout*/, immediate x, immediate y);
-extern void _TIE_xt_MAC16_MULA_DD_HL_LDINC(immediate w, const short * s /*inout*/, immediate x, immediate y);
-extern void _TIE_xt_MAC16_MULA_DD_LH_LDDEC(immediate w, const short * s /*inout*/, immediate x, immediate y);
-extern void _TIE_xt_MAC16_MULA_DD_LH_LDINC(immediate w, const short * s /*inout*/, immediate x, immediate y);
-extern void _TIE_xt_MAC16_MULA_DD_HH_LDDEC(immediate w, const short * s /*inout*/, immediate x, immediate y);
-extern void _TIE_xt_MAC16_MULA_DD_HH_LDINC(immediate w, const short * s /*inout*/, immediate x, immediate y);
-extern void _TIE_xt_MAC16_LDDEC(immediate w, const short * p /*inout*/);
-extern void _TIE_xt_MAC16_ULDDEC(immediate w, const unsigned short * p /*inout*/);
-extern void _TIE_xt_MAC16_SLDDEC(immediate w, const short * p /*inout*/);
-extern void _TIE_xt_MAC16_LDINC(immediate w, const short * p /*inout*/);
-extern void _TIE_xt_MAC16_ULDINC(immediate w, const unsigned short * p /*inout*/);
-extern void _TIE_xt_MAC16_SLDINC(immediate w, const short * p /*inout*/);
-extern int _TIE_xt_MAC16_RSR16(void);
-extern void _TIE_xt_MAC16_WSR16(int t);
-extern void _TIE_xt_MAC16_XSR16(int t /*inout*/);
-extern int _TIE_xt_MAC16_RSR17(void);
-extern void _TIE_xt_MAC16_WSR17(int t);
-extern void _TIE_xt_MAC16_XSR17(int t /*inout*/);
-#define XT_UMUL_AA_HH _TIE_xt_MAC16_UMUL_AA_HH
-#define XT_UMUL_AA_LH _TIE_xt_MAC16_UMUL_AA_LH
-#define XT_UMUL_AA_HL _TIE_xt_MAC16_UMUL_AA_HL
-#define XT_UMUL_AA_LL _TIE_xt_MAC16_UMUL_AA_LL
-#define XT_MUL_AA_HH _TIE_xt_MAC16_MUL_AA_HH
-#define XT_MUL_AA_LH _TIE_xt_MAC16_MUL_AA_LH
-#define XT_MUL_AA_HL _TIE_xt_MAC16_MUL_AA_HL
-#define XT_MUL_AA_LL _TIE_xt_MAC16_MUL_AA_LL
-#define XT_MUL_AD_HH _TIE_xt_MAC16_MUL_AD_HH
-#define XT_MUL_AD_LH _TIE_xt_MAC16_MUL_AD_LH
-#define XT_MUL_AD_HL _TIE_xt_MAC16_MUL_AD_HL
-#define XT_MUL_AD_LL _TIE_xt_MAC16_MUL_AD_LL
-#define XT_MUL_DA_HH _TIE_xt_MAC16_MUL_DA_HH
-#define XT_MUL_DA_LH _TIE_xt_MAC16_MUL_DA_LH
-#define XT_MUL_DA_HL _TIE_xt_MAC16_MUL_DA_HL
-#define XT_MUL_DA_LL _TIE_xt_MAC16_MUL_DA_LL
-#define XT_MUL_DD_HH _TIE_xt_MAC16_MUL_DD_HH
-#define XT_MUL_DD_LH _TIE_xt_MAC16_MUL_DD_LH
-#define XT_MUL_DD_HL _TIE_xt_MAC16_MUL_DD_HL
-#define XT_MUL_DD_LL _TIE_xt_MAC16_MUL_DD_LL
-#define XT_MULS_AA_HH _TIE_xt_MAC16_MULS_AA_HH
-#define XT_MULS_AA_LH _TIE_xt_MAC16_MULS_AA_LH
-#define XT_MULS_AA_HL _TIE_xt_MAC16_MULS_AA_HL
-#define XT_MULS_AA_LL _TIE_xt_MAC16_MULS_AA_LL
-#define XT_MULA_AA_HH _TIE_xt_MAC16_MULA_AA_HH
-#define XT_MULA_AA_LH _TIE_xt_MAC16_MULA_AA_LH
-#define XT_MULA_AA_HL _TIE_xt_MAC16_MULA_AA_HL
-#define XT_MULA_AA_LL _TIE_xt_MAC16_MULA_AA_LL
-#define XT_MULS_AD_HH _TIE_xt_MAC16_MULS_AD_HH
-#define XT_MULS_AD_LH _TIE_xt_MAC16_MULS_AD_LH
-#define XT_MULS_AD_HL _TIE_xt_MAC16_MULS_AD_HL
-#define XT_MULS_AD_LL _TIE_xt_MAC16_MULS_AD_LL
-#define XT_MULA_AD_HH _TIE_xt_MAC16_MULA_AD_HH
-#define XT_MULA_AD_LH _TIE_xt_MAC16_MULA_AD_LH
-#define XT_MULA_AD_HL _TIE_xt_MAC16_MULA_AD_HL
-#define XT_MULA_AD_LL _TIE_xt_MAC16_MULA_AD_LL
-#define XT_MULS_DA_HH _TIE_xt_MAC16_MULS_DA_HH
-#define XT_MULS_DA_LH _TIE_xt_MAC16_MULS_DA_LH
-#define XT_MULS_DA_HL _TIE_xt_MAC16_MULS_DA_HL
-#define XT_MULS_DA_LL _TIE_xt_MAC16_MULS_DA_LL
-#define XT_MULA_DA_HH _TIE_xt_MAC16_MULA_DA_HH
-#define XT_MULA_DA_LH _TIE_xt_MAC16_MULA_DA_LH
-#define XT_MULA_DA_HL _TIE_xt_MAC16_MULA_DA_HL
-#define XT_MULA_DA_LL _TIE_xt_MAC16_MULA_DA_LL
-#define XT_MULS_DD_HH _TIE_xt_MAC16_MULS_DD_HH
-#define XT_MULS_DD_LH _TIE_xt_MAC16_MULS_DD_LH
-#define XT_MULS_DD_HL _TIE_xt_MAC16_MULS_DD_HL
-#define XT_MULS_DD_LL _TIE_xt_MAC16_MULS_DD_LL
-#define XT_MULA_DD_HH _TIE_xt_MAC16_MULA_DD_HH
-#define XT_MULA_DD_LH _TIE_xt_MAC16_MULA_DD_LH
-#define XT_MULA_DD_HL _TIE_xt_MAC16_MULA_DD_HL
-#define XT_MULA_DD_LL _TIE_xt_MAC16_MULA_DD_LL
-#define XT_RSR_M0 _TIE_xt_MAC16_RSR_M0
-#define XT_WSR_M0 _TIE_xt_MAC16_WSR_M0
-#define XT_XSR_M0 _TIE_xt_MAC16_XSR_M0
-#define XT_RSR_M1 _TIE_xt_MAC16_RSR_M1
-#define XT_WSR_M1 _TIE_xt_MAC16_WSR_M1
-#define XT_XSR_M1 _TIE_xt_MAC16_XSR_M1
-#define XT_RSR_M2 _TIE_xt_MAC16_RSR_M2
-#define XT_WSR_M2 _TIE_xt_MAC16_WSR_M2
-#define XT_XSR_M2 _TIE_xt_MAC16_XSR_M2
-#define XT_RSR_M3 _TIE_xt_MAC16_RSR_M3
-#define XT_WSR_M3 _TIE_xt_MAC16_WSR_M3
-#define XT_XSR_M3 _TIE_xt_MAC16_XSR_M3
-#define XT_RSR_ACCLO _TIE_xt_MAC16_RSR_ACCLO
-#define XT_WSR_ACCLO _TIE_xt_MAC16_WSR_ACCLO
-#define XT_XSR_ACCLO _TIE_xt_MAC16_XSR_ACCLO
-#define XT_RSR_ACCHI _TIE_xt_MAC16_RSR_ACCHI
-#define XT_WSR_ACCHI _TIE_xt_MAC16_WSR_ACCHI
-#define XT_XSR_ACCHI _TIE_xt_MAC16_XSR_ACCHI
-#define XT_MULA_DA_LL_LDDEC _TIE_xt_MAC16_MULA_DA_LL_LDDEC
-#define XT_MULA_DA_LL_LDINC _TIE_xt_MAC16_MULA_DA_LL_LDINC
-#define XT_MULA_DA_HL_LDDEC _TIE_xt_MAC16_MULA_DA_HL_LDDEC
-#define XT_MULA_DA_HL_LDINC _TIE_xt_MAC16_MULA_DA_HL_LDINC
-#define XT_MULA_DA_LH_LDDEC _TIE_xt_MAC16_MULA_DA_LH_LDDEC
-#define XT_MULA_DA_LH_LDINC _TIE_xt_MAC16_MULA_DA_LH_LDINC
-#define XT_MULA_DA_HH_LDDEC _TIE_xt_MAC16_MULA_DA_HH_LDDEC
-#define XT_MULA_DA_HH_LDINC _TIE_xt_MAC16_MULA_DA_HH_LDINC
-#define XT_MULA_DD_LL_LDDEC _TIE_xt_MAC16_MULA_DD_LL_LDDEC
-#define XT_MULA_DD_LL_LDINC _TIE_xt_MAC16_MULA_DD_LL_LDINC
-#define XT_MULA_DD_HL_LDDEC _TIE_xt_MAC16_MULA_DD_HL_LDDEC
-#define XT_MULA_DD_HL_LDINC _TIE_xt_MAC16_MULA_DD_HL_LDINC
-#define XT_MULA_DD_LH_LDDEC _TIE_xt_MAC16_MULA_DD_LH_LDDEC
-#define XT_MULA_DD_LH_LDINC _TIE_xt_MAC16_MULA_DD_LH_LDINC
-#define XT_MULA_DD_HH_LDDEC _TIE_xt_MAC16_MULA_DD_HH_LDDEC
-#define XT_MULA_DD_HH_LDINC _TIE_xt_MAC16_MULA_DD_HH_LDINC
-#define XT_LDDEC _TIE_xt_MAC16_LDDEC
-#define XT_ULDDEC _TIE_xt_MAC16_ULDDEC
-#define XT_SLDDEC _TIE_xt_MAC16_SLDDEC
-#define XT_LDINC _TIE_xt_MAC16_LDINC
-#define XT_ULDINC _TIE_xt_MAC16_ULDINC
-#define XT_SLDINC _TIE_xt_MAC16_SLDINC
-#define XT_RSR16 _TIE_xt_MAC16_RSR16
-#define XT_WSR16 _TIE_xt_MAC16_WSR16
-#define XT_XSR16 _TIE_xt_MAC16_XSR16
-#define XT_RSR17 _TIE_xt_MAC16_RSR17
-#define XT_WSR17 _TIE_xt_MAC16_WSR17
-#define XT_XSR17 _TIE_xt_MAC16_XSR17
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_MAC16_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_MUL32.h b/components/esp32/include/xtensa/tie/xt_MUL32.h
deleted file mode 100644
index 91b3c3299c..0000000000
--- a/components/esp32/include/xtensa/tie/xt_MUL32.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Definitions for the 32-bit Integer Multiply Option. */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2009 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* NOTE: This file exists only for backward compatibility with RB-200X.x
- and earlier Xtensa releases. Starting with RC-2009.0 you should use
- . */
-
-#ifndef _XTENSA_xt_MUL32_HEADER
-#define _XTENSA_xt_MUL32_HEADER
-
-#ifdef __XTENSA__
-
-#include
-
-#endif /* __XTENSA__ */
-#endif /* !_XTENSA_xt_MUL32_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_booleans.h b/components/esp32/include/xtensa/tie/xt_booleans.h
deleted file mode 100644
index 94b5b468ed..0000000000
--- a/components/esp32/include/xtensa/tie/xt_booleans.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Definitions for the xt_booleans TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_booleans_HEADER
-#define _XTENSA_xt_booleans_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-typedef _TIE_xtbool xtbool;
-typedef _TIE_xtbool2 xtbool2;
-typedef _TIE_xtbool4 xtbool4;
-typedef _TIE_xtbool8 xtbool8;
-typedef _TIE_xtbool16 xtbool16;
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern xtbool _TIE_xt_booleans_XORB(xtbool bs, xtbool bt);
-extern xtbool _TIE_xt_booleans_ORBC(xtbool bs, xtbool bt);
-extern xtbool _TIE_xt_booleans_ORB(xtbool bs, xtbool bt);
-extern xtbool _TIE_xt_booleans_ANDBC(xtbool bs, xtbool bt);
-extern xtbool _TIE_xt_booleans_ANDB(xtbool bs, xtbool bt);
-extern xtbool _TIE_xt_booleans_ALL4(xtbool4 bs4);
-extern xtbool _TIE_xt_booleans_ANY4(xtbool4 bs4);
-extern xtbool _TIE_xt_booleans_ALL8(xtbool8 bs8);
-extern xtbool _TIE_xt_booleans_ANY8(xtbool8 bs8);
-extern void _TIE_xt_booleans_MOVT(unsigned arr /*inout*/, unsigned ars, xtbool bt);
-extern void _TIE_xt_booleans_MOVF(unsigned arr /*inout*/, unsigned ars, xtbool bt);
-#define XT_XORB _TIE_xt_booleans_XORB
-#define XT_ORBC _TIE_xt_booleans_ORBC
-#define XT_ORB _TIE_xt_booleans_ORB
-#define XT_ANDBC _TIE_xt_booleans_ANDBC
-#define XT_ANDB _TIE_xt_booleans_ANDB
-#define XT_ALL4 _TIE_xt_booleans_ALL4
-#define XT_ANY4 _TIE_xt_booleans_ANY4
-#define XT_ALL8 _TIE_xt_booleans_ALL8
-#define XT_ANY8 _TIE_xt_booleans_ANY8
-#define XT_MOVT _TIE_xt_booleans_MOVT
-#define XT_MOVF _TIE_xt_booleans_MOVF
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_booleans_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_coprocessors.h b/components/esp32/include/xtensa/tie/xt_coprocessors.h
deleted file mode 100644
index 27215cf1cd..0000000000
--- a/components/esp32/include/xtensa/tie/xt_coprocessors.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Definitions for the xt_coprocessors TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_coprocessors_HEADER
-#define _XTENSA_xt_coprocessors_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern unsigned _TIE_xt_coprocessors_RSR_CPENABLE(void);
-extern void _TIE_xt_coprocessors_WSR_CPENABLE(unsigned art);
-extern void _TIE_xt_coprocessors_XSR_CPENABLE(unsigned art /*inout*/);
-#define XT_RSR_CPENABLE _TIE_xt_coprocessors_RSR_CPENABLE
-#define XT_WSR_CPENABLE _TIE_xt_coprocessors_WSR_CPENABLE
-#define XT_XSR_CPENABLE _TIE_xt_coprocessors_XSR_CPENABLE
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_coprocessors_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_core.h b/components/esp32/include/xtensa/tie/xt_core.h
deleted file mode 100644
index 469b199e6b..0000000000
--- a/components/esp32/include/xtensa/tie/xt_core.h
+++ /dev/null
@@ -1,395 +0,0 @@
-/* Definitions for the xt_core TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_core_HEADER
-#define _XTENSA_xt_core_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern void _TIE_xt_core_ILL(void);
-extern void _TIE_xt_core_NOP(void);
-extern void _TIE_xt_core_SIMCALL(void);
-extern void _TIE_xt_core_MEMW(void);
-extern void _TIE_xt_core_EXTW(void);
-extern void _TIE_xt_core_ISYNC(void);
-extern void _TIE_xt_core_DSYNC(void);
-extern void _TIE_xt_core_ESYNC(void);
-extern void _TIE_xt_core_RSYNC(void);
-extern unsigned _TIE_xt_core_RSR_LBEG(void);
-extern void _TIE_xt_core_WSR_LBEG(unsigned art);
-extern void _TIE_xt_core_XSR_LBEG(unsigned art /*inout*/);
-extern unsigned _TIE_xt_core_RSR_CONFIGID0(void);
-extern void _TIE_xt_core_WSR_CONFIGID0(unsigned art);
-extern unsigned _TIE_xt_core_RSR_CONFIGID1(void);
-extern unsigned _TIE_xt_core_RUR_THREADPTR(void);
-extern void _TIE_xt_core_WUR_THREADPTR(unsigned v);
-extern unsigned _TIE_xt_core_uint32_loadi(const unsigned * p, immediate o);
-extern void _TIE_xt_core_uint32_storei(unsigned c, unsigned * p, immediate o);
-extern unsigned _TIE_xt_core_uint32_move(unsigned b);
-extern int _TIE_xt_core_ADDI(int s, immediate i);
-extern int _TIE_xt_core_OR(int s, int t);
-extern int _TIE_xt_core_L32I(const int * p, immediate i);
-extern void _TIE_xt_core_S32I(int r, int * p, immediate i);
-extern void _TIE_xt_core_S32NB(int r, int * p, immediate i);
-extern unsigned char _TIE_xt_core_L8UI(const unsigned char * p, immediate i);
-extern void _TIE_xt_core_S8I(signed char r, signed char * p, immediate i);
-extern unsigned short _TIE_xt_core_L16UI(const unsigned short * p, immediate i);
-extern short _TIE_xt_core_L16SI(const short * p, immediate i);
-extern void _TIE_xt_core_S16I(short r, short * p, immediate i);
-extern int _TIE_xt_core_ADDMI(int s, immediate i);
-extern int _TIE_xt_core_ADD(int s, int t);
-extern int _TIE_xt_core_ADDX2(int s, int t);
-extern int _TIE_xt_core_ADDX4(int s, int t);
-extern int _TIE_xt_core_ADDX8(int s, int t);
-extern int _TIE_xt_core_SUB(int s, int t);
-extern int _TIE_xt_core_SUBX2(int s, int t);
-extern int _TIE_xt_core_SUBX4(int s, int t);
-extern int _TIE_xt_core_SUBX8(int s, int t);
-extern int _TIE_xt_core_AND(int s, int t);
-extern int _TIE_xt_core_XOR(int s, int t);
-extern unsigned _TIE_xt_core_EXTUI(unsigned t, immediate i, immediate o);
-extern int _TIE_xt_core_MOVI(immediate i);
-extern void _TIE_xt_core_MOVEQZ(int r /*inout*/, int s, int t);
-extern void _TIE_xt_core_MOVNEZ(int r /*inout*/, int s, int t);
-extern void _TIE_xt_core_MOVLTZ(int r /*inout*/, int s, int t);
-extern void _TIE_xt_core_MOVGEZ(int r /*inout*/, int s, int t);
-extern int _TIE_xt_core_NEG(int t);
-extern int _TIE_xt_core_ABS(int t);
-extern void _TIE_xt_core_SSR(int s);
-extern void _TIE_xt_core_SSL(int s);
-extern void _TIE_xt_core_SSA8L(int s);
-extern void _TIE_xt_core_SSA8B(int s);
-extern void _TIE_xt_core_SSAI(immediate i);
-extern int _TIE_xt_core_SLL(int s);
-extern int _TIE_xt_core_SRC(int s, int t);
-extern unsigned _TIE_xt_core_SRL(unsigned t);
-extern int _TIE_xt_core_SRA(int t);
-extern int _TIE_xt_core_SLLI(int s, immediate i);
-extern int _TIE_xt_core_SRAI(int t, immediate i);
-extern unsigned _TIE_xt_core_SRLI(unsigned t, immediate i);
-extern int _TIE_xt_core_SSAI_SRC(int src1, int src2, immediate amount);
-extern int _TIE_xt_core_SSR_SRC(int src1, int src2, int amount);
-extern int _TIE_xt_core_WSR_SAR_SRC(int src1, int src2, int amount);
-extern int _TIE_xt_core_SSR_SRA(int src, int amount);
-extern unsigned _TIE_xt_core_SSR_SRL(unsigned src, int amount);
-extern int _TIE_xt_core_SSL_SLL(int src, int amount);
-extern int _TIE_xt_core_RSIL(immediate t);
-extern int _TIE_xt_core_RSR_LEND(void);
-extern void _TIE_xt_core_WSR_LEND(int t);
-extern void _TIE_xt_core_XSR_LEND(int t /*inout*/);
-extern int _TIE_xt_core_RSR_LCOUNT(void);
-extern void _TIE_xt_core_WSR_LCOUNT(int t);
-extern void _TIE_xt_core_XSR_LCOUNT(int t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_SAR(void);
-extern void _TIE_xt_core_WSR_SAR(unsigned t);
-extern void _TIE_xt_core_XSR_SAR(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_MEMCTL(void);
-extern void _TIE_xt_core_WSR_MEMCTL(unsigned t);
-extern void _TIE_xt_core_XSR_MEMCTL(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_LITBASE(void);
-extern void _TIE_xt_core_WSR_LITBASE(unsigned t);
-extern void _TIE_xt_core_XSR_LITBASE(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_PS(void);
-extern void _TIE_xt_core_WSR_PS(unsigned t);
-extern void _TIE_xt_core_XSR_PS(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPC1(void);
-extern void _TIE_xt_core_WSR_EPC1(unsigned t);
-extern void _TIE_xt_core_XSR_EPC1(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EXCSAVE1(void);
-extern void _TIE_xt_core_WSR_EXCSAVE1(unsigned t);
-extern void _TIE_xt_core_XSR_EXCSAVE1(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPC2(void);
-extern void _TIE_xt_core_WSR_EPC2(unsigned t);
-extern void _TIE_xt_core_XSR_EPC2(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EXCSAVE2(void);
-extern void _TIE_xt_core_WSR_EXCSAVE2(unsigned t);
-extern void _TIE_xt_core_XSR_EXCSAVE2(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPC3(void);
-extern void _TIE_xt_core_WSR_EPC3(unsigned t);
-extern void _TIE_xt_core_XSR_EPC3(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EXCSAVE3(void);
-extern void _TIE_xt_core_WSR_EXCSAVE3(unsigned t);
-extern void _TIE_xt_core_XSR_EXCSAVE3(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPC4(void);
-extern void _TIE_xt_core_WSR_EPC4(unsigned t);
-extern void _TIE_xt_core_XSR_EPC4(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EXCSAVE4(void);
-extern void _TIE_xt_core_WSR_EXCSAVE4(unsigned t);
-extern void _TIE_xt_core_XSR_EXCSAVE4(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPC5(void);
-extern void _TIE_xt_core_WSR_EPC5(unsigned t);
-extern void _TIE_xt_core_XSR_EPC5(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EXCSAVE5(void);
-extern void _TIE_xt_core_WSR_EXCSAVE5(unsigned t);
-extern void _TIE_xt_core_XSR_EXCSAVE5(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPC6(void);
-extern void _TIE_xt_core_WSR_EPC6(unsigned t);
-extern void _TIE_xt_core_XSR_EPC6(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EXCSAVE6(void);
-extern void _TIE_xt_core_WSR_EXCSAVE6(unsigned t);
-extern void _TIE_xt_core_XSR_EXCSAVE6(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPC7(void);
-extern void _TIE_xt_core_WSR_EPC7(unsigned t);
-extern void _TIE_xt_core_XSR_EPC7(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EXCSAVE7(void);
-extern void _TIE_xt_core_WSR_EXCSAVE7(unsigned t);
-extern void _TIE_xt_core_XSR_EXCSAVE7(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_VECBASE(void);
-extern void _TIE_xt_core_WSR_VECBASE(unsigned t);
-extern void _TIE_xt_core_XSR_VECBASE(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPS2(void);
-extern void _TIE_xt_core_WSR_EPS2(unsigned t);
-extern void _TIE_xt_core_XSR_EPS2(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPS3(void);
-extern void _TIE_xt_core_WSR_EPS3(unsigned t);
-extern void _TIE_xt_core_XSR_EPS3(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPS4(void);
-extern void _TIE_xt_core_WSR_EPS4(unsigned t);
-extern void _TIE_xt_core_XSR_EPS4(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPS5(void);
-extern void _TIE_xt_core_WSR_EPS5(unsigned t);
-extern void _TIE_xt_core_XSR_EPS5(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPS6(void);
-extern void _TIE_xt_core_WSR_EPS6(unsigned t);
-extern void _TIE_xt_core_XSR_EPS6(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EPS7(void);
-extern void _TIE_xt_core_WSR_EPS7(unsigned t);
-extern void _TIE_xt_core_XSR_EPS7(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EXCCAUSE(void);
-extern void _TIE_xt_core_WSR_EXCCAUSE(unsigned t);
-extern void _TIE_xt_core_XSR_EXCCAUSE(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_EXCVADDR(void);
-extern void _TIE_xt_core_WSR_EXCVADDR(unsigned t);
-extern void _TIE_xt_core_XSR_EXCVADDR(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_DEPC(void);
-extern void _TIE_xt_core_WSR_DEPC(unsigned t);
-extern void _TIE_xt_core_XSR_DEPC(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_MISC0(void);
-extern void _TIE_xt_core_WSR_MISC0(unsigned t);
-extern void _TIE_xt_core_XSR_MISC0(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_MISC1(void);
-extern void _TIE_xt_core_WSR_MISC1(unsigned t);
-extern void _TIE_xt_core_XSR_MISC1(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_MISC2(void);
-extern void _TIE_xt_core_WSR_MISC2(unsigned t);
-extern void _TIE_xt_core_XSR_MISC2(unsigned t /*inout*/);
-extern unsigned _TIE_xt_core_RSR_MISC3(void);
-extern void _TIE_xt_core_WSR_MISC3(unsigned t);
-extern void _TIE_xt_core_XSR_MISC3(unsigned t /*inout*/);
-extern int _TIE_xt_core_RSR_PRID(void);
-#define XT_ILL _TIE_xt_core_ILL
-#define XT_NOP _TIE_xt_core_NOP
-#define XT_SIMCALL _TIE_xt_core_SIMCALL
-#define XT_MEMW _TIE_xt_core_MEMW
-#define XT_EXTW _TIE_xt_core_EXTW
-#define XT_ISYNC _TIE_xt_core_ISYNC
-#define XT_DSYNC _TIE_xt_core_DSYNC
-#define XT_ESYNC _TIE_xt_core_ESYNC
-#define XT_RSYNC _TIE_xt_core_RSYNC
-#define XT_RSR_LBEG _TIE_xt_core_RSR_LBEG
-#define XT_WSR_LBEG _TIE_xt_core_WSR_LBEG
-#define XT_XSR_LBEG _TIE_xt_core_XSR_LBEG
-#define XT_RSR_CONFIGID0 _TIE_xt_core_RSR_CONFIGID0
-#define XT_WSR_CONFIGID0 _TIE_xt_core_WSR_CONFIGID0
-#define XT_RSR_CONFIGID1 _TIE_xt_core_RSR_CONFIGID1
-#define XT_RUR_THREADPTR _TIE_xt_core_RUR_THREADPTR
-#define RTHREADPTR _TIE_xt_core_RUR_THREADPTR
-#define RUR231 _TIE_xt_core_RUR_THREADPTR
-#define XT_WUR_THREADPTR _TIE_xt_core_WUR_THREADPTR
-#define WTHREADPTR _TIE_xt_core_WUR_THREADPTR
-#define WUR231 _TIE_xt_core_WUR_THREADPTR
-#define XT_uint32_loadi _TIE_xt_core_uint32_loadi
-#define XT_uint32_storei _TIE_xt_core_uint32_storei
-#define XT_uint32_move _TIE_xt_core_uint32_move
-#define XT_ADDI _TIE_xt_core_ADDI
-#define XT_OR _TIE_xt_core_OR
-#define XT_L32I _TIE_xt_core_L32I
-#define XT_S32I _TIE_xt_core_S32I
-#define XT_S32NB _TIE_xt_core_S32NB
-#define XT_L8UI _TIE_xt_core_L8UI
-#define XT_S8I _TIE_xt_core_S8I
-#define XT_L16UI _TIE_xt_core_L16UI
-#define XT_L16SI _TIE_xt_core_L16SI
-#define XT_S16I _TIE_xt_core_S16I
-#define XT_ADDMI _TIE_xt_core_ADDMI
-#define XT_ADD _TIE_xt_core_ADD
-#define XT_ADDX2 _TIE_xt_core_ADDX2
-#define XT_ADDX4 _TIE_xt_core_ADDX4
-#define XT_ADDX8 _TIE_xt_core_ADDX8
-#define XT_SUB _TIE_xt_core_SUB
-#define XT_SUBX2 _TIE_xt_core_SUBX2
-#define XT_SUBX4 _TIE_xt_core_SUBX4
-#define XT_SUBX8 _TIE_xt_core_SUBX8
-#define XT_AND _TIE_xt_core_AND
-#define XT_XOR _TIE_xt_core_XOR
-#define XT_EXTUI _TIE_xt_core_EXTUI
-#define XT_MOVI _TIE_xt_core_MOVI
-#define XT_MOVEQZ _TIE_xt_core_MOVEQZ
-#define XT_MOVNEZ _TIE_xt_core_MOVNEZ
-#define XT_MOVLTZ _TIE_xt_core_MOVLTZ
-#define XT_MOVGEZ _TIE_xt_core_MOVGEZ
-#define XT_NEG _TIE_xt_core_NEG
-#define XT_ABS _TIE_xt_core_ABS
-#define XT_SSR _TIE_xt_core_SSR
-#define XT_SSL _TIE_xt_core_SSL
-#define XT_SSA8L _TIE_xt_core_SSA8L
-#define XT_SSA8B _TIE_xt_core_SSA8B
-#define XT_SSAI _TIE_xt_core_SSAI
-#define XT_SLL _TIE_xt_core_SLL
-#define XT_SRC _TIE_xt_core_SRC
-#define XT_SRL _TIE_xt_core_SRL
-#define XT_SRA _TIE_xt_core_SRA
-#define XT_SLLI _TIE_xt_core_SLLI
-#define XT_SRAI _TIE_xt_core_SRAI
-#define XT_SRLI _TIE_xt_core_SRLI
-#define XT_SSAI_SRC _TIE_xt_core_SSAI_SRC
-#define XT_SSR_SRC _TIE_xt_core_SSR_SRC
-#define XT_WSR_SAR_SRC _TIE_xt_core_WSR_SAR_SRC
-#define XT_SSR_SRA _TIE_xt_core_SSR_SRA
-#define XT_SSR_SRL _TIE_xt_core_SSR_SRL
-#define XT_SSL_SLL _TIE_xt_core_SSL_SLL
-#define XT_RSIL _TIE_xt_core_RSIL
-#define XT_RSR_LEND _TIE_xt_core_RSR_LEND
-#define XT_WSR_LEND _TIE_xt_core_WSR_LEND
-#define XT_XSR_LEND _TIE_xt_core_XSR_LEND
-#define XT_RSR_LCOUNT _TIE_xt_core_RSR_LCOUNT
-#define XT_WSR_LCOUNT _TIE_xt_core_WSR_LCOUNT
-#define XT_XSR_LCOUNT _TIE_xt_core_XSR_LCOUNT
-#define XT_RSR_SAR _TIE_xt_core_RSR_SAR
-#define XT_WSR_SAR _TIE_xt_core_WSR_SAR
-#define XT_XSR_SAR _TIE_xt_core_XSR_SAR
-#define XT_RSR_MEMCTL _TIE_xt_core_RSR_MEMCTL
-#define XT_WSR_MEMCTL _TIE_xt_core_WSR_MEMCTL
-#define XT_XSR_MEMCTL _TIE_xt_core_XSR_MEMCTL
-#define XT_RSR_LITBASE _TIE_xt_core_RSR_LITBASE
-#define XT_WSR_LITBASE _TIE_xt_core_WSR_LITBASE
-#define XT_XSR_LITBASE _TIE_xt_core_XSR_LITBASE
-#define XT_RSR_PS _TIE_xt_core_RSR_PS
-#define XT_WSR_PS _TIE_xt_core_WSR_PS
-#define XT_XSR_PS _TIE_xt_core_XSR_PS
-#define XT_RSR_EPC1 _TIE_xt_core_RSR_EPC1
-#define XT_WSR_EPC1 _TIE_xt_core_WSR_EPC1
-#define XT_XSR_EPC1 _TIE_xt_core_XSR_EPC1
-#define XT_RSR_EXCSAVE1 _TIE_xt_core_RSR_EXCSAVE1
-#define XT_WSR_EXCSAVE1 _TIE_xt_core_WSR_EXCSAVE1
-#define XT_XSR_EXCSAVE1 _TIE_xt_core_XSR_EXCSAVE1
-#define XT_RSR_EPC2 _TIE_xt_core_RSR_EPC2
-#define XT_WSR_EPC2 _TIE_xt_core_WSR_EPC2
-#define XT_XSR_EPC2 _TIE_xt_core_XSR_EPC2
-#define XT_RSR_EXCSAVE2 _TIE_xt_core_RSR_EXCSAVE2
-#define XT_WSR_EXCSAVE2 _TIE_xt_core_WSR_EXCSAVE2
-#define XT_XSR_EXCSAVE2 _TIE_xt_core_XSR_EXCSAVE2
-#define XT_RSR_EPC3 _TIE_xt_core_RSR_EPC3
-#define XT_WSR_EPC3 _TIE_xt_core_WSR_EPC3
-#define XT_XSR_EPC3 _TIE_xt_core_XSR_EPC3
-#define XT_RSR_EXCSAVE3 _TIE_xt_core_RSR_EXCSAVE3
-#define XT_WSR_EXCSAVE3 _TIE_xt_core_WSR_EXCSAVE3
-#define XT_XSR_EXCSAVE3 _TIE_xt_core_XSR_EXCSAVE3
-#define XT_RSR_EPC4 _TIE_xt_core_RSR_EPC4
-#define XT_WSR_EPC4 _TIE_xt_core_WSR_EPC4
-#define XT_XSR_EPC4 _TIE_xt_core_XSR_EPC4
-#define XT_RSR_EXCSAVE4 _TIE_xt_core_RSR_EXCSAVE4
-#define XT_WSR_EXCSAVE4 _TIE_xt_core_WSR_EXCSAVE4
-#define XT_XSR_EXCSAVE4 _TIE_xt_core_XSR_EXCSAVE4
-#define XT_RSR_EPC5 _TIE_xt_core_RSR_EPC5
-#define XT_WSR_EPC5 _TIE_xt_core_WSR_EPC5
-#define XT_XSR_EPC5 _TIE_xt_core_XSR_EPC5
-#define XT_RSR_EXCSAVE5 _TIE_xt_core_RSR_EXCSAVE5
-#define XT_WSR_EXCSAVE5 _TIE_xt_core_WSR_EXCSAVE5
-#define XT_XSR_EXCSAVE5 _TIE_xt_core_XSR_EXCSAVE5
-#define XT_RSR_EPC6 _TIE_xt_core_RSR_EPC6
-#define XT_WSR_EPC6 _TIE_xt_core_WSR_EPC6
-#define XT_XSR_EPC6 _TIE_xt_core_XSR_EPC6
-#define XT_RSR_EXCSAVE6 _TIE_xt_core_RSR_EXCSAVE6
-#define XT_WSR_EXCSAVE6 _TIE_xt_core_WSR_EXCSAVE6
-#define XT_XSR_EXCSAVE6 _TIE_xt_core_XSR_EXCSAVE6
-#define XT_RSR_EPC7 _TIE_xt_core_RSR_EPC7
-#define XT_WSR_EPC7 _TIE_xt_core_WSR_EPC7
-#define XT_XSR_EPC7 _TIE_xt_core_XSR_EPC7
-#define XT_RSR_EXCSAVE7 _TIE_xt_core_RSR_EXCSAVE7
-#define XT_WSR_EXCSAVE7 _TIE_xt_core_WSR_EXCSAVE7
-#define XT_XSR_EXCSAVE7 _TIE_xt_core_XSR_EXCSAVE7
-#define XT_RSR_VECBASE _TIE_xt_core_RSR_VECBASE
-#define XT_WSR_VECBASE _TIE_xt_core_WSR_VECBASE
-#define XT_XSR_VECBASE _TIE_xt_core_XSR_VECBASE
-#define XT_RSR_EPS2 _TIE_xt_core_RSR_EPS2
-#define XT_WSR_EPS2 _TIE_xt_core_WSR_EPS2
-#define XT_XSR_EPS2 _TIE_xt_core_XSR_EPS2
-#define XT_RSR_EPS3 _TIE_xt_core_RSR_EPS3
-#define XT_WSR_EPS3 _TIE_xt_core_WSR_EPS3
-#define XT_XSR_EPS3 _TIE_xt_core_XSR_EPS3
-#define XT_RSR_EPS4 _TIE_xt_core_RSR_EPS4
-#define XT_WSR_EPS4 _TIE_xt_core_WSR_EPS4
-#define XT_XSR_EPS4 _TIE_xt_core_XSR_EPS4
-#define XT_RSR_EPS5 _TIE_xt_core_RSR_EPS5
-#define XT_WSR_EPS5 _TIE_xt_core_WSR_EPS5
-#define XT_XSR_EPS5 _TIE_xt_core_XSR_EPS5
-#define XT_RSR_EPS6 _TIE_xt_core_RSR_EPS6
-#define XT_WSR_EPS6 _TIE_xt_core_WSR_EPS6
-#define XT_XSR_EPS6 _TIE_xt_core_XSR_EPS6
-#define XT_RSR_EPS7 _TIE_xt_core_RSR_EPS7
-#define XT_WSR_EPS7 _TIE_xt_core_WSR_EPS7
-#define XT_XSR_EPS7 _TIE_xt_core_XSR_EPS7
-#define XT_RSR_EXCCAUSE _TIE_xt_core_RSR_EXCCAUSE
-#define XT_WSR_EXCCAUSE _TIE_xt_core_WSR_EXCCAUSE
-#define XT_XSR_EXCCAUSE _TIE_xt_core_XSR_EXCCAUSE
-#define XT_RSR_EXCVADDR _TIE_xt_core_RSR_EXCVADDR
-#define XT_WSR_EXCVADDR _TIE_xt_core_WSR_EXCVADDR
-#define XT_XSR_EXCVADDR _TIE_xt_core_XSR_EXCVADDR
-#define XT_RSR_DEPC _TIE_xt_core_RSR_DEPC
-#define XT_WSR_DEPC _TIE_xt_core_WSR_DEPC
-#define XT_XSR_DEPC _TIE_xt_core_XSR_DEPC
-#define XT_RSR_MISC0 _TIE_xt_core_RSR_MISC0
-#define XT_WSR_MISC0 _TIE_xt_core_WSR_MISC0
-#define XT_XSR_MISC0 _TIE_xt_core_XSR_MISC0
-#define XT_RSR_MISC1 _TIE_xt_core_RSR_MISC1
-#define XT_WSR_MISC1 _TIE_xt_core_WSR_MISC1
-#define XT_XSR_MISC1 _TIE_xt_core_XSR_MISC1
-#define XT_RSR_MISC2 _TIE_xt_core_RSR_MISC2
-#define XT_WSR_MISC2 _TIE_xt_core_WSR_MISC2
-#define XT_XSR_MISC2 _TIE_xt_core_XSR_MISC2
-#define XT_RSR_MISC3 _TIE_xt_core_RSR_MISC3
-#define XT_WSR_MISC3 _TIE_xt_core_WSR_MISC3
-#define XT_XSR_MISC3 _TIE_xt_core_XSR_MISC3
-#define XT_RSR_PRID _TIE_xt_core_RSR_PRID
-
-#ifndef RUR
-#define RUR(NUM) RUR##NUM()
-#endif
-
-#ifndef WUR
-#define WUR(VAL, NUM) WUR##NUM(VAL)
-#endif
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_core_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_debug.h b/components/esp32/include/xtensa/tie/xt_debug.h
deleted file mode 100644
index 676fd33c78..0000000000
--- a/components/esp32/include/xtensa/tie/xt_debug.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Definitions for the xt_debug TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_debug_HEADER
-#define _XTENSA_xt_debug_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern void _TIE_xt_debug_BREAK(immediate imms, immediate immt);
-extern void _TIE_xt_debug_BREAK_N(immediate imms);
-extern unsigned _TIE_xt_debug_RSR_DBREAKA0(void);
-extern void _TIE_xt_debug_WSR_DBREAKA0(unsigned art);
-extern void _TIE_xt_debug_XSR_DBREAKA0(unsigned art /*inout*/);
-extern unsigned _TIE_xt_debug_RSR_DBREAKC0(void);
-extern void _TIE_xt_debug_WSR_DBREAKC0(unsigned art);
-extern void _TIE_xt_debug_XSR_DBREAKC0(unsigned art /*inout*/);
-extern unsigned _TIE_xt_debug_RSR_DBREAKA1(void);
-extern void _TIE_xt_debug_WSR_DBREAKA1(unsigned art);
-extern void _TIE_xt_debug_XSR_DBREAKA1(unsigned art /*inout*/);
-extern unsigned _TIE_xt_debug_RSR_DBREAKC1(void);
-extern void _TIE_xt_debug_WSR_DBREAKC1(unsigned art);
-extern void _TIE_xt_debug_XSR_DBREAKC1(unsigned art /*inout*/);
-extern unsigned _TIE_xt_debug_RSR_IBREAKA0(void);
-extern void _TIE_xt_debug_WSR_IBREAKA0(unsigned art);
-extern void _TIE_xt_debug_XSR_IBREAKA0(unsigned art /*inout*/);
-extern unsigned _TIE_xt_debug_RSR_IBREAKA1(void);
-extern void _TIE_xt_debug_WSR_IBREAKA1(unsigned art);
-extern void _TIE_xt_debug_XSR_IBREAKA1(unsigned art /*inout*/);
-extern unsigned _TIE_xt_debug_RSR_IBREAKENABLE(void);
-extern void _TIE_xt_debug_WSR_IBREAKENABLE(unsigned art);
-extern void _TIE_xt_debug_XSR_IBREAKENABLE(unsigned art /*inout*/);
-extern unsigned _TIE_xt_debug_RSR_DEBUGCAUSE(void);
-extern void _TIE_xt_debug_WSR_DEBUGCAUSE(unsigned art);
-extern void _TIE_xt_debug_XSR_DEBUGCAUSE(unsigned art /*inout*/);
-extern unsigned _TIE_xt_debug_RSR_ICOUNT(void);
-extern void _TIE_xt_debug_WSR_ICOUNT(unsigned art);
-extern void _TIE_xt_debug_XSR_ICOUNT(unsigned art /*inout*/);
-extern unsigned _TIE_xt_debug_RSR_ICOUNTLEVEL(void);
-extern void _TIE_xt_debug_WSR_ICOUNTLEVEL(unsigned art);
-extern void _TIE_xt_debug_XSR_ICOUNTLEVEL(unsigned art /*inout*/);
-extern unsigned _TIE_xt_debug_RSR_DDR(void);
-extern void _TIE_xt_debug_WSR_DDR(unsigned art);
-extern void _TIE_xt_debug_XSR_DDR(unsigned art /*inout*/);
-extern void _TIE_xt_debug_LDDR32_P(const void * ars /*inout*/);
-extern void _TIE_xt_debug_SDDR32_P(void * ars /*inout*/);
-#define XT_BREAK _TIE_xt_debug_BREAK
-#define XT_BREAK_N _TIE_xt_debug_BREAK_N
-#define XT_RSR_DBREAKA0 _TIE_xt_debug_RSR_DBREAKA0
-#define XT_WSR_DBREAKA0 _TIE_xt_debug_WSR_DBREAKA0
-#define XT_XSR_DBREAKA0 _TIE_xt_debug_XSR_DBREAKA0
-#define XT_RSR_DBREAKC0 _TIE_xt_debug_RSR_DBREAKC0
-#define XT_WSR_DBREAKC0 _TIE_xt_debug_WSR_DBREAKC0
-#define XT_XSR_DBREAKC0 _TIE_xt_debug_XSR_DBREAKC0
-#define XT_RSR_DBREAKA1 _TIE_xt_debug_RSR_DBREAKA1
-#define XT_WSR_DBREAKA1 _TIE_xt_debug_WSR_DBREAKA1
-#define XT_XSR_DBREAKA1 _TIE_xt_debug_XSR_DBREAKA1
-#define XT_RSR_DBREAKC1 _TIE_xt_debug_RSR_DBREAKC1
-#define XT_WSR_DBREAKC1 _TIE_xt_debug_WSR_DBREAKC1
-#define XT_XSR_DBREAKC1 _TIE_xt_debug_XSR_DBREAKC1
-#define XT_RSR_IBREAKA0 _TIE_xt_debug_RSR_IBREAKA0
-#define XT_WSR_IBREAKA0 _TIE_xt_debug_WSR_IBREAKA0
-#define XT_XSR_IBREAKA0 _TIE_xt_debug_XSR_IBREAKA0
-#define XT_RSR_IBREAKA1 _TIE_xt_debug_RSR_IBREAKA1
-#define XT_WSR_IBREAKA1 _TIE_xt_debug_WSR_IBREAKA1
-#define XT_XSR_IBREAKA1 _TIE_xt_debug_XSR_IBREAKA1
-#define XT_RSR_IBREAKENABLE _TIE_xt_debug_RSR_IBREAKENABLE
-#define XT_WSR_IBREAKENABLE _TIE_xt_debug_WSR_IBREAKENABLE
-#define XT_XSR_IBREAKENABLE _TIE_xt_debug_XSR_IBREAKENABLE
-#define XT_RSR_DEBUGCAUSE _TIE_xt_debug_RSR_DEBUGCAUSE
-#define XT_WSR_DEBUGCAUSE _TIE_xt_debug_WSR_DEBUGCAUSE
-#define XT_XSR_DEBUGCAUSE _TIE_xt_debug_XSR_DEBUGCAUSE
-#define XT_RSR_ICOUNT _TIE_xt_debug_RSR_ICOUNT
-#define XT_WSR_ICOUNT _TIE_xt_debug_WSR_ICOUNT
-#define XT_XSR_ICOUNT _TIE_xt_debug_XSR_ICOUNT
-#define XT_RSR_ICOUNTLEVEL _TIE_xt_debug_RSR_ICOUNTLEVEL
-#define XT_WSR_ICOUNTLEVEL _TIE_xt_debug_WSR_ICOUNTLEVEL
-#define XT_XSR_ICOUNTLEVEL _TIE_xt_debug_XSR_ICOUNTLEVEL
-#define XT_RSR_DDR _TIE_xt_debug_RSR_DDR
-#define XT_WSR_DDR _TIE_xt_debug_WSR_DDR
-#define XT_XSR_DDR _TIE_xt_debug_XSR_DDR
-#define XT_LDDR32_P _TIE_xt_debug_LDDR32_P
-#define XT_SDDR32_P _TIE_xt_debug_SDDR32_P
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_debug_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_density.h b/components/esp32/include/xtensa/tie/xt_density.h
deleted file mode 100644
index da5c51ccf0..0000000000
--- a/components/esp32/include/xtensa/tie/xt_density.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Definitions for the xt_density TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_density_HEADER
-#define _XTENSA_xt_density_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern void _TIE_xt_density_ILL_N(void);
-extern void _TIE_xt_density_NOP_N(void);
-extern int _TIE_xt_density_L32I_N(const int * p, immediate i);
-extern void _TIE_xt_density_S32I_N(int t, int * p, immediate i);
-extern int _TIE_xt_density_ADD_N(int s, int t);
-extern int _TIE_xt_density_ADDI_N(int s, immediate i);
-extern int _TIE_xt_density_MOV_N(int s);
-extern int _TIE_xt_density_MOVI_N(immediate i);
-#define XT_ILL_N _TIE_xt_density_ILL_N
-#define XT_NOP_N _TIE_xt_density_NOP_N
-#define XT_L32I_N _TIE_xt_density_L32I_N
-#define XT_S32I_N _TIE_xt_density_S32I_N
-#define XT_ADD_N _TIE_xt_density_ADD_N
-#define XT_ADDI_N _TIE_xt_density_ADDI_N
-#define XT_MOV_N _TIE_xt_density_MOV_N
-#define XT_MOVI_N _TIE_xt_density_MOVI_N
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_density_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_exceptions.h b/components/esp32/include/xtensa/tie/xt_exceptions.h
deleted file mode 100644
index 64fb393079..0000000000
--- a/components/esp32/include/xtensa/tie/xt_exceptions.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Definitions for the xt_exceptions TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_exceptions_HEADER
-#define _XTENSA_xt_exceptions_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern void _TIE_xt_exceptions_EXCW(void);
-extern void _TIE_xt_exceptions_SYSCALL(void);
-#define XT_EXCW _TIE_xt_exceptions_EXCW
-#define XT_SYSCALL _TIE_xt_exceptions_SYSCALL
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_exceptions_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_externalregisters.h b/components/esp32/include/xtensa/tie/xt_externalregisters.h
deleted file mode 100644
index 3196527c2f..0000000000
--- a/components/esp32/include/xtensa/tie/xt_externalregisters.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Definitions for the xt_externalregisters TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_externalregisters_HEADER
-#define _XTENSA_xt_externalregisters_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern unsigned _TIE_xt_externalregisters_RER(unsigned ars);
-extern void _TIE_xt_externalregisters_WER(unsigned art, unsigned ars);
-#define XT_RER _TIE_xt_externalregisters_RER
-#define XT_WER _TIE_xt_externalregisters_WER
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_externalregisters_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_integerdivide.h b/components/esp32/include/xtensa/tie/xt_integerdivide.h
deleted file mode 100644
index 9fbe9615b7..0000000000
--- a/components/esp32/include/xtensa/tie/xt_integerdivide.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Definitions for the xt_integerdivide TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_integerdivide_HEADER
-#define _XTENSA_xt_integerdivide_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern unsigned _TIE_xt_integerdivide_REMS(unsigned ars, unsigned art);
-extern unsigned _TIE_xt_integerdivide_REMU(unsigned ars, unsigned art);
-extern unsigned _TIE_xt_integerdivide_QUOS(unsigned ars, unsigned art);
-extern unsigned _TIE_xt_integerdivide_QUOU(unsigned ars, unsigned art);
-#define XT_REMS _TIE_xt_integerdivide_REMS
-#define XT_REMU _TIE_xt_integerdivide_REMU
-#define XT_QUOS _TIE_xt_integerdivide_QUOS
-#define XT_QUOU _TIE_xt_integerdivide_QUOU
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_integerdivide_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_interrupt.h b/components/esp32/include/xtensa/tie/xt_interrupt.h
deleted file mode 100644
index b20c94f47a..0000000000
--- a/components/esp32/include/xtensa/tie/xt_interrupt.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Definitions for the xt_interrupt TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_interrupt_HEADER
-#define _XTENSA_xt_interrupt_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern void _TIE_xt_interrupt_WAITI(immediate s);
-extern unsigned _TIE_xt_interrupt_RSR_INTERRUPT(void);
-extern void _TIE_xt_interrupt_WSR_INTSET(unsigned art);
-extern void _TIE_xt_interrupt_WSR_INTCLEAR(unsigned art);
-extern unsigned _TIE_xt_interrupt_RSR_INTENABLE(void);
-extern void _TIE_xt_interrupt_WSR_INTENABLE(unsigned art);
-extern void _TIE_xt_interrupt_XSR_INTENABLE(unsigned art /*inout*/);
-#define XT_WAITI _TIE_xt_interrupt_WAITI
-#define XT_RSR_INTERRUPT _TIE_xt_interrupt_RSR_INTERRUPT
-#define XT_WSR_INTSET _TIE_xt_interrupt_WSR_INTSET
-#define XT_WSR_INTCLEAR _TIE_xt_interrupt_WSR_INTCLEAR
-#define XT_RSR_INTENABLE _TIE_xt_interrupt_RSR_INTENABLE
-#define XT_WSR_INTENABLE _TIE_xt_interrupt_WSR_INTENABLE
-#define XT_XSR_INTENABLE _TIE_xt_interrupt_XSR_INTENABLE
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_interrupt_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_ioports.h b/components/esp32/include/xtensa/tie/xt_ioports.h
deleted file mode 100644
index 0253bea4cf..0000000000
--- a/components/esp32/include/xtensa/tie/xt_ioports.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Definitions for the xt_ioports TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_ioports_HEADER
-#define _XTENSA_xt_ioports_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern unsigned _TIE_xt_ioports_READ_IMPWIRE(void);
-extern void _TIE_xt_ioports_SETB_EXPSTATE(immediate bitindex);
-extern void _TIE_xt_ioports_CLRB_EXPSTATE(immediate bitindex);
-extern void _TIE_xt_ioports_WRMSK_EXPSTATE(unsigned art, unsigned ars);
-extern unsigned _TIE_xt_ioports_RUR_EXPSTATE(void);
-extern void _TIE_xt_ioports_WUR_EXPSTATE(unsigned v);
-#define READ_IMPWIRE _TIE_xt_ioports_READ_IMPWIRE
-#define SETB_EXPSTATE _TIE_xt_ioports_SETB_EXPSTATE
-#define CLRB_EXPSTATE _TIE_xt_ioports_CLRB_EXPSTATE
-#define WRMSK_EXPSTATE _TIE_xt_ioports_WRMSK_EXPSTATE
-#define RUR_EXPSTATE _TIE_xt_ioports_RUR_EXPSTATE
-#define REXPSTATE _TIE_xt_ioports_RUR_EXPSTATE
-#define RUR230 _TIE_xt_ioports_RUR_EXPSTATE
-#define WUR_EXPSTATE _TIE_xt_ioports_WUR_EXPSTATE
-#define WEXPSTATE _TIE_xt_ioports_WUR_EXPSTATE
-#define WUR230 _TIE_xt_ioports_WUR_EXPSTATE
-
-#ifndef RUR
-#define RUR(NUM) RUR##NUM()
-#endif
-
-#ifndef WUR
-#define WUR(VAL, NUM) WUR##NUM(VAL)
-#endif
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_ioports_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_misc.h b/components/esp32/include/xtensa/tie/xt_misc.h
deleted file mode 100644
index a0b36f4e5d..0000000000
--- a/components/esp32/include/xtensa/tie/xt_misc.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Definitions for the xt_misc TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_misc_HEADER
-#define _XTENSA_xt_misc_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern int _TIE_xt_misc_CLAMPS(int s, immediate i);
-extern int _TIE_xt_misc_MIN(int s, int t);
-extern int _TIE_xt_misc_MAX(int s, int t);
-extern unsigned _TIE_xt_misc_MINU(unsigned s, unsigned t);
-extern unsigned _TIE_xt_misc_MAXU(unsigned s, unsigned t);
-extern int _TIE_xt_misc_NSA(int s);
-extern unsigned _TIE_xt_misc_NSAU(unsigned s);
-extern int _TIE_xt_misc_SEXT(int s, immediate i);
-#define XT_CLAMPS _TIE_xt_misc_CLAMPS
-#define XT_MIN _TIE_xt_misc_MIN
-#define XT_MAX _TIE_xt_misc_MAX
-#define XT_MINU _TIE_xt_misc_MINU
-#define XT_MAXU _TIE_xt_misc_MAXU
-#define XT_NSA _TIE_xt_misc_NSA
-#define XT_NSAU _TIE_xt_misc_NSAU
-#define XT_SEXT _TIE_xt_misc_SEXT
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_misc_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_mmu.h b/components/esp32/include/xtensa/tie/xt_mmu.h
deleted file mode 100644
index ce786c0fea..0000000000
--- a/components/esp32/include/xtensa/tie/xt_mmu.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Definitions for the xt_mmu TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_mmu_HEADER
-#define _XTENSA_xt_mmu_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern void _TIE_xt_mmu_IDTLB(unsigned ars);
-extern unsigned _TIE_xt_mmu_RDTLB1(unsigned ars);
-extern unsigned _TIE_xt_mmu_RDTLB0(unsigned ars);
-extern unsigned _TIE_xt_mmu_PDTLB(unsigned ars);
-extern void _TIE_xt_mmu_WDTLB(unsigned art, unsigned ars);
-extern void _TIE_xt_mmu_IITLB(unsigned ars);
-extern unsigned _TIE_xt_mmu_RITLB1(unsigned ars);
-extern unsigned _TIE_xt_mmu_RITLB0(unsigned ars);
-extern unsigned _TIE_xt_mmu_PITLB(unsigned ars);
-extern void _TIE_xt_mmu_WITLB(unsigned art, unsigned ars);
-#define XT_IDTLB _TIE_xt_mmu_IDTLB
-#define XT_RDTLB1 _TIE_xt_mmu_RDTLB1
-#define XT_RDTLB0 _TIE_xt_mmu_RDTLB0
-#define XT_PDTLB _TIE_xt_mmu_PDTLB
-#define XT_WDTLB _TIE_xt_mmu_WDTLB
-#define XT_IITLB _TIE_xt_mmu_IITLB
-#define XT_RITLB1 _TIE_xt_mmu_RITLB1
-#define XT_RITLB0 _TIE_xt_mmu_RITLB0
-#define XT_PITLB _TIE_xt_mmu_PITLB
-#define XT_WITLB _TIE_xt_mmu_WITLB
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_mmu_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_mul.h b/components/esp32/include/xtensa/tie/xt_mul.h
deleted file mode 100644
index e20862069d..0000000000
--- a/components/esp32/include/xtensa/tie/xt_mul.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Definitions for the xt_mul TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_mul_HEADER
-#define _XTENSA_xt_mul_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern int _TIE_xt_mul_MUL16S(short s, short t);
-extern unsigned _TIE_xt_mul_MUL16U(unsigned short s, unsigned short t);
-extern int _TIE_xt_mul_MULL(int s, int t);
-extern unsigned _TIE_xt_mul_MULUH(unsigned s, unsigned t);
-extern int _TIE_xt_mul_MULSH(int s, int t);
-#define XT_MUL16S _TIE_xt_mul_MUL16S
-#define XT_MUL16U _TIE_xt_mul_MUL16U
-#define XT_MULL _TIE_xt_mul_MULL
-#define XT_MULUH _TIE_xt_mul_MULUH
-#define XT_MULSH _TIE_xt_mul_MULSH
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_mul_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_regwin.h b/components/esp32/include/xtensa/tie/xt_regwin.h
deleted file mode 100644
index 7bce471a03..0000000000
--- a/components/esp32/include/xtensa/tie/xt_regwin.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Definitions for the xt_regwin TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_regwin_HEADER
-#define _XTENSA_xt_regwin_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern void _TIE_xt_regwin_ENTRY(unsigned ars /*inout*/, immediate uimm12x8);
-extern void _TIE_xt_regwin_ROTW(immediate simm4);
-extern int _TIE_xt_regwin_MOVSP(int s);
-extern int _TIE_xt_regwin_L32E(const int * s, immediate o);
-extern void _TIE_xt_regwin_S32E(int t, int * s, immediate o);
-extern unsigned _TIE_xt_regwin_RSR_WINDOWBASE(void);
-extern void _TIE_xt_regwin_WSR_WINDOWBASE(unsigned t);
-extern void _TIE_xt_regwin_XSR_WINDOWBASE(unsigned t /*inout*/);
-extern unsigned _TIE_xt_regwin_RSR_WINDOWSTART(void);
-extern void _TIE_xt_regwin_WSR_WINDOWSTART(unsigned t);
-extern void _TIE_xt_regwin_XSR_WINDOWSTART(unsigned t /*inout*/);
-#define XT_ENTRY _TIE_xt_regwin_ENTRY
-#define XT_ROTW _TIE_xt_regwin_ROTW
-#define XT_MOVSP _TIE_xt_regwin_MOVSP
-#define XT_L32E _TIE_xt_regwin_L32E
-#define XT_S32E _TIE_xt_regwin_S32E
-#define XT_RSR_WINDOWBASE _TIE_xt_regwin_RSR_WINDOWBASE
-#define XT_WSR_WINDOWBASE _TIE_xt_regwin_WSR_WINDOWBASE
-#define XT_XSR_WINDOWBASE _TIE_xt_regwin_XSR_WINDOWBASE
-#define XT_RSR_WINDOWSTART _TIE_xt_regwin_RSR_WINDOWSTART
-#define XT_WSR_WINDOWSTART _TIE_xt_regwin_WSR_WINDOWSTART
-#define XT_XSR_WINDOWSTART _TIE_xt_regwin_XSR_WINDOWSTART
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_regwin_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_scmpr.h b/components/esp32/include/xtensa/tie/xt_scmpr.h
deleted file mode 100644
index 337c7762eb..0000000000
--- a/components/esp32/include/xtensa/tie/xt_scmpr.h
+++ /dev/null
@@ -1,22 +0,0 @@
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_scmpr_h_HEADER
-#define _XTENSA_xt_scmpr_h_HEADER
-
-
-/* Header includes start */
-
-
-/* Header includes end */
-
-#endif /* !_XTENSA_xt_scmpr_h_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_sync.h b/components/esp32/include/xtensa/tie/xt_sync.h
deleted file mode 100644
index 9323dfe4b8..0000000000
--- a/components/esp32/include/xtensa/tie/xt_sync.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Definitions for the xt_sync TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_sync_HEADER
-#define _XTENSA_xt_sync_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern unsigned _TIE_xt_sync_RSR_SCOMPARE1(void);
-extern void _TIE_xt_sync_WSR_SCOMPARE1(unsigned art);
-extern void _TIE_xt_sync_XSR_SCOMPARE1(unsigned art /*inout*/);
-extern unsigned _TIE_xt_sync_RSR_ATOMCTL(void);
-extern void _TIE_xt_sync_WSR_ATOMCTL(unsigned art);
-extern void _TIE_xt_sync_XSR_ATOMCTL(unsigned art /*inout*/);
-extern unsigned _TIE_xt_sync_L32AI(const unsigned * p, immediate o);
-extern void _TIE_xt_sync_S32RI(unsigned c, unsigned * p, immediate o);
-extern void _TIE_xt_sync_S32C1I(unsigned c /*inout*/, const unsigned * p, immediate o);
-#define XT_RSR_SCOMPARE1 _TIE_xt_sync_RSR_SCOMPARE1
-#define XT_WSR_SCOMPARE1 _TIE_xt_sync_WSR_SCOMPARE1
-#define XT_XSR_SCOMPARE1 _TIE_xt_sync_XSR_SCOMPARE1
-#define XT_RSR_ATOMCTL _TIE_xt_sync_RSR_ATOMCTL
-#define XT_WSR_ATOMCTL _TIE_xt_sync_WSR_ATOMCTL
-#define XT_XSR_ATOMCTL _TIE_xt_sync_XSR_ATOMCTL
-#define XT_L32AI _TIE_xt_sync_L32AI
-#define XT_S32RI _TIE_xt_sync_S32RI
-#define XT_S32C1I _TIE_xt_sync_S32C1I
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_sync_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_timer.h b/components/esp32/include/xtensa/tie/xt_timer.h
deleted file mode 100644
index 64db45c1a4..0000000000
--- a/components/esp32/include/xtensa/tie/xt_timer.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Definitions for the xt_timer TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_timer_HEADER
-#define _XTENSA_xt_timer_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern unsigned _TIE_xt_timer_RSR_CCOUNT(void);
-extern void _TIE_xt_timer_WSR_CCOUNT(unsigned art);
-extern void _TIE_xt_timer_XSR_CCOUNT(unsigned art /*inout*/);
-extern unsigned _TIE_xt_timer_RSR_CCOMPARE0(void);
-extern void _TIE_xt_timer_WSR_CCOMPARE0(unsigned art);
-extern void _TIE_xt_timer_XSR_CCOMPARE0(unsigned art /*inout*/);
-extern unsigned _TIE_xt_timer_RSR_CCOMPARE1(void);
-extern void _TIE_xt_timer_WSR_CCOMPARE1(unsigned art);
-extern void _TIE_xt_timer_XSR_CCOMPARE1(unsigned art /*inout*/);
-extern unsigned _TIE_xt_timer_RSR_CCOMPARE2(void);
-extern void _TIE_xt_timer_WSR_CCOMPARE2(unsigned art);
-extern void _TIE_xt_timer_XSR_CCOMPARE2(unsigned art /*inout*/);
-#define XT_RSR_CCOUNT _TIE_xt_timer_RSR_CCOUNT
-#define XT_WSR_CCOUNT _TIE_xt_timer_WSR_CCOUNT
-#define XT_XSR_CCOUNT _TIE_xt_timer_XSR_CCOUNT
-#define XT_RSR_CCOMPARE0 _TIE_xt_timer_RSR_CCOMPARE0
-#define XT_WSR_CCOMPARE0 _TIE_xt_timer_WSR_CCOMPARE0
-#define XT_XSR_CCOMPARE0 _TIE_xt_timer_XSR_CCOMPARE0
-#define XT_RSR_CCOMPARE1 _TIE_xt_timer_RSR_CCOMPARE1
-#define XT_WSR_CCOMPARE1 _TIE_xt_timer_WSR_CCOMPARE1
-#define XT_XSR_CCOMPARE1 _TIE_xt_timer_XSR_CCOMPARE1
-#define XT_RSR_CCOMPARE2 _TIE_xt_timer_RSR_CCOMPARE2
-#define XT_WSR_CCOMPARE2 _TIE_xt_timer_WSR_CCOMPARE2
-#define XT_XSR_CCOMPARE2 _TIE_xt_timer_XSR_CCOMPARE2
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_timer_HEADER */
diff --git a/components/esp32/include/xtensa/tie/xt_trace.h b/components/esp32/include/xtensa/tie/xt_trace.h
deleted file mode 100644
index 8d8d07fa48..0000000000
--- a/components/esp32/include/xtensa/tie/xt_trace.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Definitions for the xt_trace TIE package */
-
-/*
- * Customer ID=11657; Build=0x5fe96; Copyright (c) 2004-2010 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-/* Do not modify. This is automatically generated.*/
-
-#ifndef _XTENSA_xt_trace_HEADER
-#define _XTENSA_xt_trace_HEADER
-
-#ifdef __XTENSA__
-#ifdef __XCC__
-
-#include
-
-/*
- * The following prototypes describe intrinsic functions
- * corresponding to TIE instructions. Some TIE instructions
- * may produce multiple results (designated as "out" operands
- * in the iclass section) or may have operands used as both
- * inputs and outputs (designated as "inout"). However, the C
- * and C++ languages do not provide syntax that can express
- * the in/out/inout constraints of TIE intrinsics.
- * Nevertheless, the compiler understands these constraints
- * and will check that the intrinsic functions are used
- * correctly. To improve the readability of these prototypes,
- * the "out" and "inout" parameters are marked accordingly
- * with comments.
- */
-
-extern void _TIE_xt_trace_WSR_MMID(unsigned art);
-#define XT_WSR_MMID _TIE_xt_trace_WSR_MMID
-
-#endif /* __XCC__ */
-
-#endif /* __XTENSA__ */
-
-#endif /* !_XTENSA_xt_trace_HEADER */
diff --git a/components/esp32/include/xtensa/trax-api.h b/components/esp32/include/xtensa/trax-api.h
deleted file mode 100644
index aa1584359b..0000000000
--- a/components/esp32/include/xtensa/trax-api.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Misc TRAX API function definitions.
-
- Copyright (c) 2007-2012 Tensilica Inc.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#ifndef _TRAX_API_H_
-#define _TRAX_API_H_
-
-#include
-#include
-#include "tpack.h"
-#include "traxreg.h"
-
-#include "xdm-regs.h"
-
-/* Flags for trax_stop(): */
-#define TRAX_STOP_HALT 0x0001 /* halt immediately, don't wait for post-stop-trigger capture */
-#define TRAX_STOP_QUIET 0x0002 /* don't display informative messages */
-
-
-/*
- * Describes a TRAX channel (based on tpack).
- */
-typedef struct {
- tpack_channel chan; /* channel structure header */
- /* Per TRAX unit information: */
- int trax_version; /* TRAX_ID_VER(id), one of TRAX_VER_xxx macros */
- unsigned long trax_tram_size; /* size of trace RAM in bytes */
- int trax_erratum10; /* set if TRAX 1.0 erratum workarounds needed */
- int trax_erratum20; /* set if TRAX 2.0 erratum workaround needed (PR 22161)*/
- int trax_erratum20_size;
- int trax_has_busy; /* has trace-busy feature */
- int trax_has_atb; /* has ATB feature */
- /*FIXME: add various features: coresight regs (don't call it that), APB, ATB, TRAM, ... */
-} trax_channel;
-
-
-/* Prototypes: */
-
-/* TRAX Protocol API: */
-extern int trax_read_register(tpack_channel *tchan, int regno, unsigned *value);
-extern int trax_write_register(tpack_channel *tchan, int regno, unsigned value);
-extern int trax_read_memory(tpack_channel *tchan, int address, int size, unsigned char *pdata);
-extern int trax_fill_memory(tpack_channel *tchan, int address, int size, tpack_u32 pattern);
-extern int trax_enumerate_devices(tpack_channel *tchan, int * buf, int * size);
-
-/* TRAX Network API: */
-extern unsigned long trax_ram_size(tpack_channel *traxchan);
-extern unsigned long trax_ram_size_addr(tpack_channel *traxchan);
-extern int trax_create_tracefile(tpack_channel *traxchan, int size, unsigned char * data,
- char *filename, int hflags, const char *toolver);
-extern int trax_memaccess_safe(tpack_channel *traxchan, const char *what);
-extern int trax_start(tpack_channel *traxchan, int flags);
-extern int trax_stop(tpack_channel *traxchan, int flags);
-extern int trax_halt(tpack_channel *traxchan, int flags);
-extern int trax_save(tpack_channel *traxchan, char *filename, int flags, const char *toolver, int erratum);
-
-/* TRAX Misc API (no network dependencies): */
-int trax_fixed_hw(unsigned * regs);
-extern int trax_display_id(unsigned id, const char *prefix);
-extern int trax_display_summary(unsigned id,
- unsigned status,
- unsigned control,
- unsigned address,
- unsigned delay,
- unsigned trigger,
- unsigned match,
- unsigned startaddr,
- unsigned endaddr,
- const char *prefix);
-
-/* Other: */
-
-#endif /* _TRAX_API_H_ */
-
diff --git a/components/esp32/include/xtensa/trax-core-config.h b/components/esp32/include/xtensa/trax-core-config.h
deleted file mode 100644
index 42a03334aa..0000000000
--- a/components/esp32/include/xtensa/trax-core-config.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/* Definitions for Xtensa processor config info needed for TRAX.
-
- Copyright (c) 2005-2011 Tensilica Inc.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#ifndef TRAX_CORE_CONFIG_H
-#define TRAX_CORE_CONFIG_H
-
-#include "xtensa-params.h"
-
-/*
- * Vector Enumerations.
- */
-
-/* These must match the LX2.0 and later traceport spec: */
-#define VEC_NO_VECTOR 0
-#define VEC_FIRST VEC_RESET /* first valid vector */
-#define VEC_RESET 1
-#define VEC_DEBUG 2
-#define VEC_NMI 3
-#define VEC_USER 4
-#define VEC_KERNEL 5
-#define VEC_DOUBLE 6
-#define VEC_MEMERR 7
-#define VEC_RESERVED8 8
-#define VEC_RESERVED9 9
-#define VEC_WINO4 10
-#define VEC_WINU4 11
-#define VEC_WINO8 12
-#define VEC_WINU8 13
-#define VEC_WINO12 14
-#define VEC_WINU12 15
-#define VEC_INTLEVEL2 16
-#define VEC_INTLEVEL3 17
-#define VEC_INTLEVEL4 18
-#define VEC_INTLEVEL5 19
-#define VEC_INTLEVEL6 20
-/* These are internal, i.e. don't appear like this on traceport: */
-#define VEC_DEBUG_OCD 21
-#define VEC_UNKNOWN 22
-/* Enumerations 23 through 31 are also reserved, but putting */
-/* placeholders here seems wasteful and unnecessary. */
-#define VEC_COUNT 23
-
-/* Other branch (change-of-PC-flow) type encodings;
- * if PC changes due to an exception or interrupt vector,
- * one of the VEC_* values above is used, otherwise
- * (or if it's unknown whether it's due to an exception/interrupt)
- * one of the following is used: */
-
-#define BRANCH_IS_VEC(n) ((n) < VEC_COUNT) /* is known to be except/interrupt? */
-#define BRANCH_OR_VEC 24 /* unknown type of branch (branch/exception/interrupt/etc) */
-#define BRANCH_UNKNOWN 25 /* unknown type of branch (anything but except/interrupt) */
-#define BRANCH_UNKNOWN_ERR 26 /* like BRANCH_UNKNOWN with known error (non-branch instr) */
-#define BRANCH_LOOPBACK 28 /* zero-overhead loopback (from LEND to LBEG) */
-#define BRANCH_CONDTAKEN 29 /* conditional branch taken (or LOOP{NEZ,GTZ} loop skip) */
-#define BRANCH_JUMP 30 /* jump (unconditional branch, i.e. J or JX) */
-#define BRANCH_IS_CALL(n) (((n) & ~3) == 32) /* is a function call? */
-#define BRANCH_CALL0 32 /* non-windowed function call (CALL0, CALLX0) */
-#define BRANCH_CALL4 33 /* windowed function call (CALL4, CALLX4) */
-#define BRANCH_CALL8 34 /* windowed function call (CALL8, CALLX8) */
-#define BRANCH_CALL12 35 /* windowed function call (CALL12, CALLX12) */
-#define BRANCH_IS_RETURN(n) ((n) >= 36) /* is any kind of return? */
-#define BRANCH_IS_CALLRETURN(n) (((n) & ~1) == 36) /* is a function return? */
-#define BRANCH_RET 36 /* non-windowed function return (RET or RET.N) */
-#define BRANCH_RETW 37 /* windowed function return (RETW or RETW.N) */
-#define BRANCH_IS_EIRETURN(n) ((n) >= 38) /* is an except/inter. return? */
-#define BRANCH_RFE 38 /* RFE or RFUE */
-#define BRANCH_RFDE 39 /* RFDE */
-#define BRANCH_RFWO 40 /* RFWO */
-#define BRANCH_RFWU 41 /* RFWU */
-#define BRANCH_RFI_2 42 /* RFI 2 */
-#define BRANCH_RFI_3 43 /* RFI 3 */
-#define BRANCH_RFI_4 44 /* RFI 4 */
-#define BRANCH_RFI_5 45 /* RFI 5 */
-#define BRANCH_RFI_6 46 /* RFI 6 */
-#define BRANCH_RFI_NMI 47 /* RFI NMILEVEL */
-#define BRANCH_RFI_DEBUG 48 /* RFI DEBUGLEVEL */
-#define BRANCH_RFME 49 /* RFME */
-#define BRANCH_COUNT 50 /* (number of defined BRANCH_xxx values) */
-
-
-
-typedef struct {
- unsigned vaddr;
- unsigned vaddr2; /* for static vectors only (reloc vectors option) */
- int is_configured;
-} trax_vector_t;
-
-
-/*
- * This structure describes those portion of a Tensilica processor's
- * configuration that are useful for trace.
- */
-typedef struct {
- char ** isa_dlls;
- char * core_name; /* (XPG core name, not necessarily same as XTENSA_CORE) */
- int big_endian; /* 0 = little-endian, 1 = big-endian */
- int has_loops; /* 1 = zero overhead loops configured */
- int has_autorefill; /* 1 = TLB autorefill (MMU) configured */
- unsigned max_instr_size; /* in bytes (eg. 3, 4, 8, ...) */
- unsigned int_level_max; /* number of interrupt levels configured (without NMI) */
- int debug_level; /* debug intlevel, 0 if debug not configured */
- int nmi_level; /* NMI intlevel, 0 if NMI not configured */
- unsigned targethw_min; /* min. targeted hardware version (XTENSA_HWVERSION_) */
- unsigned targethw_max; /* max. targeted hardware version (XTENSA_HWVERSION_) */
- int reloc_vectors; /* 0 = fixed vectors, 1 = relocatable vectors */
- int statvec_select; /* 0 = stat vec base 0, 1 = stat vec base 1 (SW default) */
- int vecbase_align; /* number of bits to align VECBASE (32 - bits in VECBASE) */
- unsigned statvec_base0; /* static vector base 0 */
- unsigned statvec_base1; /* static vector base 1 */
- unsigned vecbase_reset; /* reset value of VECBASE */
- trax_vector_t vectors[VEC_COUNT]; /* all vectors... */
-} trax_core_config_t;
-
-
-/* Globals: */
-//extern const char * const trax_vector_short_names[/*VEC_COUNT*/]; // nobody uses this one
-extern const char * const trax_vector_names[/*VEC_COUNT*/];
-
-/* Prototypes: */
-extern int trax_read_params (trax_core_config_t *c, xtensa_params p);
-extern int trax_vector_from_address(trax_core_config_t *config, unsigned long vaddr, unsigned long *vecbases);
-
-#endif /* TRAX_CORE_CONFIG_H */
-
diff --git a/components/esp32/include/xtensa/trax-proto.h b/components/esp32/include/xtensa/trax-proto.h
deleted file mode 100644
index 41d5c9fd76..0000000000
--- a/components/esp32/include/xtensa/trax-proto.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* This file contains functions that are hidden from the user. These are
- * protocol specific functions used to read and write TRAX registers
- * and the trace memory
- */
-
-/*
- * Copyright (c) 2012-2013 Tensilica Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#ifndef _TRAX_PROTO_H
-#define _TRAX_PROTO_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Function to read register
- *
- * regno : The register number to be read (not ERI addressed)
- * data : Location where the read value is kept
- *
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_read_register_eri (int regno, unsigned *data);
-
-/* Function to write a value into a register
- *
- * regno : The register number to be written (not ERI addressed)
- * value : The value to be written at that register location
- *
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_write_register_eri (int regno, unsigned value);
-
-/* Function to read memory
- *
- * address : Address of the TraceRAM memory, each location has a word
- * len : Amount of memory in bytes, to be read
- * data : buffer in which the read memory is stored
- * final_address: Next address to be read in the following call to this
- * function (trace save mechanism)
- *
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_read_memory_eri (unsigned address, int len, int *data,
- unsigned *final_address);
-
-/* Function to write a value to the memory address
- *
- * address : Address of the TraceRAM memory
- * value : The value to be written inside that location
- *
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_write_memory_eri (int address, unsigned value);
-
-/* Function to write to a subfield of the register.
- * Called by set and show parameter functions.
- *
- * regno : Register number
- * regmask : Mask in order to toggle appropriate bits
- * value : Value to be written in the masked location
- *
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_write_register_field_eri (int regno, unsigned regmask,
- unsigned value);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/components/esp32/include/xtensa/trax-util.h b/components/esp32/include/xtensa/trax-util.h
deleted file mode 100644
index 123ac366df..0000000000
--- a/components/esp32/include/xtensa/trax-util.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* This file contains utility functions that can be used for polling TRAX
- * or executing higher level save functionality
- * It assumes that print subroutines and file I/O routines are available
- * on the system
- */
-
-/*
- * Copyright (c) 2012-2013 Tensilica Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _TRAX_UTIL_H
-#define _TRAX_UTIL_H
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* User can use this function if he wants to generate a tracefile output.
- * Internally it calls trax_get_trace in a loop until it realizes that
- * the entire trace has been read.
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * filename : user specified output trace file name. If the file does not
- * exist, it would create the new file, else would append to it
- *
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_save (trax_context *context, char *filename);
-
-/* Displays a brief machine readable status.
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_poll (trax_context *context);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/components/esp32/include/xtensa/trax.h b/components/esp32/include/xtensa/trax.h
deleted file mode 100644
index 47049c51d2..0000000000
--- a/components/esp32/include/xtensa/trax.h
+++ /dev/null
@@ -1,409 +0,0 @@
-/* Header file for TRAX control Library */
-
-/*
- * Copyright (c) 2012-2013 Tensilica Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _TRAX_H
-#define _TRAX_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define TRAX_STOP_HALT 0x0001
-#define TRAX_STOP_QUIET 0x0002
-
-/* Flag values to indicate if the user wanted to reverse the pcstop
- * parameters */
-#define TRAX_PCSTOP_REVERSE 0x0001
-#define TRAX_PCSTOP_NO_REVERSE 0x0000
-
-/* Indicating whether postsize should be in terms of bytes, instructions
- * or percentage of trace size captured */
-#define TRAX_POSTSIZE_BYTES 0x0000
-#define TRAX_POSTSIZE_INSTR 0x0001
-#define TRAX_POSTSIZE_PERCENT 0x0002
-
-/* Size of the header inside the trace file */
-#define TRAX_HEADER_SIZE 256
-
-/* Minimum size between start and end addresses */
-#define TRAX_MIN_TRACEMEM 64
-
-/* For basic debugging */
-#define DEBUG 0
-
-#include
-
-#define ffs(i) __builtin_ffs(i)
-
-/* Data structures */
-
-/* Represents the context of the TRAX unit and the current TRAX session.
- * To be used by set and show function calls to set and show appropriate
- * parameters of appropriate TRAX unit.
- */
-
-typedef struct {
- int trax_version; /* TRAX PC version information */
- unsigned long trax_tram_size; /* If trace RAM is present,size of it */
- int hflags; /* Flags that can be used to debug,
- print info, etc. */
- int address_read_last; /* During saving of the trace, this
- indicates the address from which
- the current trace reading must
- resume */
- unsigned long bytes_read; /* bytes read uptil now */
- unsigned long total_memlen; /* Total bytes to be read based on the
- trace collected in the trace RAM */
- bool get_trace_started; /* indicates that the first chunk of
- bytes (which include the header) has
- been read */
-} trax_context;
-
-
-/* -----------------------TRAX Initialization ------------------------------*/
-
-/* Initializing the trax context. Reads registers and sets values for version,
- * trace RAM size, total memory length, etc. Most of the other values are
- * initialized to their default case.
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- *
- * returns : 0 if successful, -1 if unsuccessful, -2 if ram_size if
- * incorrect
- */
-int trax_context_init_eri (trax_context *context);
-
-/* -----------------Starting/Stopping TRAX session -------------------------*/
-
-/* Start tracing with current parameter setting. If tracing is already in
- * progress, an error is reported. Otherwise, tracing starts and any unsaved
- * contents of the TraceRAM is discarded
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * returns : 0 if successful, 1 if trace is already active,
- * -1 if unsuccessful
- */
-int trax_start (trax_context *context);
-
-/* This command initiates a stop trigger or halts a trace session based of the
- * value of the flag parameter passed. In case stop trigger is initiated, any
- * selected post-stop-trigger capture proceeds normally.
- * If trace capture was not in progress, or a stop was already triggered, the
- * return value indicates appropriately.
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * flags : To differentiate between stopping trace without any
- * post-size-trigger capture (trax_halt) or with that.
- * A zero value would stop the trace based on trigger and a
- * value of one would halt it
- *
- * returns : 0 if successful, 1 if already stopped, -1 if unsuccessful
- */
-int trax_stop_halt (trax_context *context, int flags);
-
-/* Resets the TRAX parameters to their default values which would internally
- * involve resetting the TRAX registers. To invoke another trace session or
- * reset the current tracing mechanism, this function needs to be called as
- * it resets parameters of the context that deal with tracing information
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- *
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_reset (trax_context *context);
-
-/* ---------------Set/Get several TRAX parameters --------------------------*/
-
-/* Sets the start address and end address (word aligned) of the trace in the
- * TraceRAM. Care must be taken to ensure that the difference between the
- * start and the end addresses is atleast TRAX_MIN_TRACEMEM bytes. If not,
- * the values are reset to default, which is 0 for startaddr and
- * traceRAM_words -1 for endaddr
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * startaddr : value to which the start address must be set. Can be
- * any value between 0 - (traceRAM_words - 1)
- * endaddr : value to which the end address must be set. Can be any value
- * between 0 - (traceRAM_words - 1)
- *
- * returns : 0 if successful, -1 if unsuccessful, -2 if the difference
- * between the start and end addresses is less than
- * TRAX_MIN_TRACEMEM bytes or if they are passed incorrect
- * values, -3 if memory shared option is not configured, in
- * which case, start and end addresses are set to default
- * values instead of those passed by the user
- */
-int trax_set_ram_boundaries (trax_context *context, unsigned startaddr,
- unsigned endaddr);
-
-/* Shows the start address and end address(word aligned) of the trace in the
- * TraceRAM. If incorrect, the startaddress and the endaddress values are
- * set to default, i.e. 0 for startaddr and traceRAM_words - 1 for endaddr
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * startaddr : pointer to value which will contain the start address
- * endaddr : pointer to value which will contain the end address
- *
- * returns : 0 if successful, -1 if unsuccessful
- *
- */
-int trax_get_ram_boundaries (trax_context *context, unsigned *startaddr,
- unsigned *endaddr);
-
-/* Selects stop trigger via cross-trigger input
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * value : 0 = off (reset value), 1 = on
- *
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_set_ctistop (trax_context *context, unsigned value);
-
-/* Shows if stop-trigger via cross-trigger input is off or on
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * returns : 0 if off, 1 if on, -1 if unsuccessful
- */
-int trax_get_ctistop (trax_context *context);
-
-/* Selects stop trigger via processor-trigger input
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * value : 0 = off (reset value), 1 = on
- *
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_set_ptistop (trax_context *context, unsigned value);
-
-/* Shows if stop trigger visa processor-trigger input is off or on
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * returns : 0 if off, 1 if on, -1 if unsuccessful
- */
-int trax_get_ptistop (trax_context *context);
-
-/* Reports cross trigger output state
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * returns : 0 if CTO bit is reset, 1 if CTO bit is set
- */
-int trax_get_cto (trax_context *context);
-
-/* Reports processor trigger output state
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * returns : 0 if PTO bit is reset, 1 if PTO bit is set
- */
-int trax_get_pto (trax_context *context);
-
-/* Selects condition that asserts cross trigger output
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * option : 0 = off(reset value)/1 = ontrig/2 = onhalt
- *
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_set_ctowhen (trax_context *context, int option);
-
-/* Shows condition that asserted cross trigger output. It can be
- * any of: ontrig or onhalt or even off
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- *
- * returns : 0 if off, 1 if ontrig, 2 if onhalt, -1 if unsuccessful
- */
-int trax_get_ctowhen (trax_context *context);
-
-/* Selects condition that asserts processor trigger output
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * option : 0 = off(reset value)/1 = ontrig/2 = onhalt
- *
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_set_ptowhen (trax_context *context, int option);
-
-
-/* Shows condition that asserted processor trigger output. It can be
- * any of: ontrig or onhalt or even off
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * returns : 0 if off, 1 if ontrig, 2 if onhalt, -1 if unsuccessful
- */
-int trax_get_ptowhen (trax_context *context);
-
-/* Selects the trace synchronization message period.
- * If ATEN enabled, we cannot allow syncper to be off, set it to reset value.
- * Also, if no trace RAM, and ATEN enabled, set syncper to be reset value
- * i.e. 256. A value of 1 i.e. on indicates that internally the message
- * frequency is set to an optimal value. This option should be preferred
- * if the user is not sure what message frequency option to set for the
- * trace session.
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * option : 0 = off, 1 = on, -1 = auto, 8, 16, 32, 64, 128,
- * 256 (reset value)
- *
- * returns : 0 if successful, -1 if unsuccessful, -2 if incorrect
- * arguments
- */
-int trax_set_syncper (trax_context *context, int option);
-
-/* Shows trace synchronization message period. Can be one of:
- * off, on, auto, 8, 16, 32, 64, 128, 256 (reset value)
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * returns : value of sync period, 0 if off, -1 if unsuccessful
- */
-int trax_get_syncper (trax_context *context);
-
-/* Selects stop trigger via PC match. Specifies the address or
- * address range to match against program counter. Trace stops when the
- * processor executes an instruction matching the specified address
- * or range.
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * index : indicates the number of stop trigger (currently there is
- * only one i.e. index = 0)
- * startaddress : start range of the address at which the stop trigger
- * should be activated
- * enaddress : end range of the address at which the stop trigger should
- * be activated
- * flags : If non-zero, this inverts the range. i.e. trace stops
- * when the processor executes an instruction that does not
- * match the specified address or range
- *
- * returns : 0 if successful, -1 if unsuccessful, -2 if incorrect
- * arguments (unaligned)
- *
- * Note : For the current version of TRAX library, the endaddress and
- * startaddress can differ by at most 31 bytes and the total
- * range i.e. (endaddress - startaddress + 1) has to be a power
- * of two
- */
-int trax_set_pcstop (trax_context *context, int index, unsigned long startaddress,
- unsigned long endaddress, int flags);
-
-/* Shows the stop trigger via PC match
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * index : container of information about the number of stop triggers
- * startaddress : container of start range of stop trigger
- * endaddress : container of end range of stop trigger
- * flags : container of information whcih indicates whether the
- * pc stop range is inverted or not.
- *
- * returns : 0 if successful, -1 if unsuccessful
- */
-int trax_get_pcstop (trax_context *context, int *index,
- unsigned long *startaddress,
- unsigned long *endaddress, int *flags);
-
-/* This function is used to set the amount of trace to be captured past
- * the stop trigger.
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * count_unit : contains the count of units (instructions or bytes) to be
- * captured post trigger. If 0, it implies that this is off
- * unit : unit of measuring the count. 0 is bytes, 1 is instructions
- * 2 is percentage of trace
- *
- * returns : 0 if successful, -1 if unsuccessful, -2 if incorrect
- * arguments
- *
- */
-int trax_set_postsize (trax_context *context, int count_unit, int unit);
-
-/* This function shows the amount of TraceRAM in terms of the number of
- * instructions or bytes, captured post the stop trigger
- *
- * context : pointer to structure which contains information about the
- * current TRAX session
- * count_unit : will contain the count of units(instructions or bytes) post
- * trigger
- * unit : will contain information about the events that are counted
- * 0 implies that the traceRAM words consumed are counted and
- * 1 implies that the target processor instructions executed and
- * excpetions/interrupts taken are counted
- *
- * returns : 0 if postsize was got successfully, -1 if unsuccessful
- */
-int trax_get_postsize (trax_context *context, int *count_unit, int *unit);
-
-/* -------------------------- TRAX save routines ---------------------------*/
-
-/* This function should be called by the user to return a chunk of
- * bytes in buf. It can be a lower layer function of save, or can be
- * called by the user explicitly. If bytes_actually_read contains a 0
- * after a call to this function has been made, it implies that the entire
- * trace has been read successfully.
- *
- * context : pointer to structure which contains information about
- * the current TRAX session
- * buf : Buffer that is allocated by the user, all the trace
- * data read would be put in this buffer, which can then
- * be used to generate a tracefile.
- * The first TRAX_HEADER_SIZE of the buffer will always
- * contain the header information.
- * bytes_to_be_read : Indicates the bytes the user wants to read. The first
- * invocation would need this parameter to be
- * TRAX_HEADER_SIZE at least.
- *
- * returns : bytes actually read during the call to this function.
- * 0 implies that all the bytes in the trace have been
- * read, -1 if unsuccessful read/write of
- * registers or memory, -2 if trace was active while
- * this function was called, -3 if user enters
- * bytes_to_be_read < TRAX_HEADER_SIZE in the first
- * pass
- */
-int trax_get_trace (trax_context *context, void *buf,
- int bytes_to_be_read);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _TRAX_H */
diff --git a/components/esp32/include/xtensa/traxfile.h b/components/esp32/include/xtensa/traxfile.h
deleted file mode 100644
index 4afc926a50..0000000000
--- a/components/esp32/include/xtensa/traxfile.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* TRAX file header definition.
-
- Copyright (c) 2007-2012 Tensilica Inc.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-
-#define TRAX_FHEAD_MAGIC "TRAXdmp"
-#define TRAX_FHEAD_VERSION 1
-
-/* Header flags: */
-#define TRAX_FHEADF_OCD_ENABLED 0x00000001 /* set if OCD was enabled while capturing trace */
-#define TRAX_FHEADF_TESTDUMP 0x00000002 /* set if is a test file
- (from 'memsave' instead of 'save') */
-#define TRAX_FHEADF_OCD_ENABLED_WHILE_EXIT 0x00000004 /* set if OCD was enabled while capturing trace and
- we were exiting the OCD mode */
-
-/* Header at the start of a TRAX dump file. */
-typedef struct {
- char magic[8]; /* 00: "TRAXdmp\0" (TRAX_FHEAD_MAGIC) */
- char endianness; /* 08: 0=little-endian, 1=big-endian */
- char version; /* 09: TRAX_FHEAD_VERSION */
- char reserved0[2]; /* 0A: ... */
- unsigned filesize; /* 0C: size of the trace file, including this header */
- unsigned trace_ofs; /* 10: start of trace output, byte offset from start of header */
- unsigned trace_size; /* 14: size of trace output in bytes */
- unsigned dumptime; /* 18: date/time of capture save (secs since 1970-01-01), 0 if unknown */
- unsigned flags; /* 1C: misc flags (TRAX_FHEAD_F_xxx) */
- char username[16]; /* 20: user doing the capture/save (up to 15 chars) */
- char toolver[24]; /* 30: tool + version used for capture/save (up to 23 chars) */
- char reserved2[40]; /* 48: (reserved - could be hostname used for dump (up to 39 chars)) */
- unsigned configid[2]; /* 70: processor ConfigID values, 0 if unknown */
- unsigned ts_freq; /* 78: timestamp frequency, 0 if not specified */
- unsigned reserved3; /* 7C: (reserved) */
- unsigned id; /* 80: TRAX registers at time of save (0 if not read) */
- unsigned control;
- unsigned status;
- unsigned reserved4; /* Data register (should not be read) */
- unsigned address;
- unsigned trigger;
- unsigned match;
- unsigned delay;
- unsigned trax_regs[24]; /*100: (total size) -- dummy allocation (FIXME) */
-} trax_file_header;
-
diff --git a/components/esp32/include/xtensa/uart-16550-board.h b/components/esp32/include/xtensa/uart-16550-board.h
deleted file mode 100644
index 8ef8af1637..0000000000
--- a/components/esp32/include/xtensa/uart-16550-board.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*******************************************************************************
-Copyright (c) 2006-2013 by Tensilica Inc. ALL RIGHTS RESERVED.
-These coded instructions, statements, and computer programs are the
-copyrighted works and confidential proprietary information of Tensilica Inc.
-They may not be modified, copied, reproduced, distributed, or disclosed to
-third parties in any manner, medium, or form, in whole or in part, without
-the prior written consent of Tensilica Inc.
---------------------------------------------------------------------------------
-
-uart-16550-board.h Board-specific UART info on these boards:
- Avnet AV60 (XT-AV60)
- Avnet AV110 (XT-AV110)
- Avnet AV200 (XT-AV200)
- Xilinx ML605 (XT-ML605)
- Xilinx KC705 (XT-KC705)
-
-Interface between board-independent driver and board-specific header.
-
-This is used by a board-independent 16550 UART driver to obtain board-specific
-information about 1 instance of the 16550 UART on the board, such as the device
-register base address and spacing (a function of how the address lines are
-connected on the board) and the frequency of the UART clock. The driver does
-not refer directly to the board-specific header, which therefore is not
-constrained to use macro names consistent with other boards.
-
-!! Must not contain any board-specific macro names (only UART specific). !!
-
-Included at compile-time via an include path specific to the board.
-
-These boards contain a single 16550 UART implemented on the FPGA.
-Their clock frequency comes from the board's core clock (not its own crystal)
-which depends on the core config so is not a constant. Obtained via the BSP.
-
-*******************************************************************************/
-
-#ifndef _UART_16550_BOARD_H
-#define _UART_16550_BOARD_H
-
-#include /* BSP API */
-#include /* Board info */
-
-
-/* Base address of UART's registers. */
-#ifdef UART16550_VADDR
-#define UART_16550_REGBASE UART16550_VADDR
-#endif
-
-/*
-The UART's registers are connected at word addresses on these boards.
-Each byte-wide register appears as the least-significant-byte (LSB) of the
-word regardless of the endianness of the processor.
-*/
-#define UART_16550_REGSPACING 4
-typedef unsigned uart16550_reg_t;
-
-/* UART Clock Frequency in Hz */
-#define UART_16550_XTAL_FREQ xtbsp_clock_freq_hz()
-
-/* UART Interrupt Number */
-#ifdef UART16550_INTNUM
-#define UART_16550_INTNUM UART16550_INTNUM
-#endif
-
-
-/* Include generic information shared by all boards that use this device. */
-#include
-
-#endif /* _UART_16550_BOARD_H */
-
diff --git a/components/esp32/include/xtensa/uart-16550.h b/components/esp32/include/xtensa/uart-16550.h
deleted file mode 100644
index c551c64c13..0000000000
--- a/components/esp32/include/xtensa/uart-16550.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*******************************************************************************
-
- Copyright (c) 2006-2007 Tensilica Inc.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
---------------------------------------------------------------------------------
-
-uart-16550.h Generic definitions for National Semiconductor 16550 UART
-
-This is used by board-support-packages with one or more 16550 compatible UARTs.
-A BSP provides a base address for each instance of a 16550 UART on the board.
-
-Note that a 16552 DUART (Dual UART) is simply two instances of a 16550 UART.
-
-*******************************************************************************/
-
-#ifndef _UART_16550_H_
-#define _UART_16550_H_
-
-/* C interface to UART registers. */
-struct uart_dev_s {
- union {
- uart16550_reg_t rxb; /* DLAB=0: receive buffer, read-only */
- uart16550_reg_t txb; /* DLAB=0: transmit buffer, write-only */
- uart16550_reg_t dll; /* DLAB=1: divisor, LS byte latch */
- } w0;
- union {
- uart16550_reg_t ier; /* DLAB=0: interrupt-enable register */
- uart16550_reg_t dlm; /* DLAB=1: divisor, MS byte latch */
- } w1;
-
- union {
- uart16550_reg_t isr; /* DLAB=0: interrupt status register, read-only */
- uart16550_reg_t fcr; /* DLAB=0: FIFO control register, write-only */
- uart16550_reg_t afr; /* DLAB=1: alternate function register */
- } w2;
-
- uart16550_reg_t lcr; /* line control-register, write-only */
- uart16550_reg_t mcr; /* modem control-regsiter, write-only */
- uart16550_reg_t lsr; /* line status register, read-only */
- uart16550_reg_t msr; /* modem status register, read-only */
- uart16550_reg_t scr; /* scratch regsiter, read/write */
-};
-
-
-#define _RXB(u) ((u)->w0.rxb)
-#define _TXB(u) ((u)->w0.txb)
-#define _DLL(u) ((u)->w0.dll)
-#define _IER(u) ((u)->w1.ier)
-#define _DLM(u) ((u)->w1.dlm)
-#define _ISR(u) ((u)->w2.isr)
-#define _FCR(u) ((u)->w2.fcr)
-#define _AFR(u) ((u)->w2.afr)
-#define _LCR(u) ((u)->lcr)
-#define _MCR(u) ((u)->mcr)
-#define _LSR(u) ((u)->lsr)
-#define _MSR(u) ((u)->msr)
-#define _SCR(u) ((u)->scr)
-
-typedef volatile struct uart_dev_s uart_dev_t;
-
-/* IER bits */
-#define RCVR_DATA_REG_INTENABLE 0x01
-#define XMIT_HOLD_REG_INTENABLE 0x02
-#define RCVR_STATUS_INTENABLE 0x04
-#define MODEM_STATUS_INTENABLE 0x08
-
-/* FCR bits */
-#define _FIFO_ENABLE 0x01
-#define RCVR_FIFO_RESET 0x02
-#define XMIT_FIFO_RESET 0x04
-#define DMA_MODE_SELECT 0x08
-#define RCVR_TRIGGER_LSB 0x40
-#define RCVR_TRIGGER_MSB 0x80
-
-/* AFR bits */
-#define AFR_CONC_WRITE 0x01
-#define AFR_BAUDOUT_SEL 0x02
-#define AFR_RXRDY_SEL 0x04
-
-/* ISR bits */
-#define INT_STATUS(r) ((r)&1)
-#define INT_PRIORITY(r) (((r)>>1)&0x7)
-
-/* LCR bits */
-#define WORD_LENGTH(n) (((n)-5)&0x3)
-#define STOP_BIT_ENABLE 0x04
-#define PARITY_ENABLE 0x08
-#define EVEN_PARITY 0x10
-#define FORCE_PARITY 0x20
-#define XMIT_BREAK 0x40
-#define DLAB_ENABLE 0x80
-
-/* MCR bits */
-#define _DTR 0x01
-#define _RTS 0x02
-#define _OP1 0x04
-#define _OP2 0x08
-#define LOOP_BACK 0x10
-
-/* LSR Bits */
-#define RCVR_DATA_READY 0x01
-#define OVERRUN_ERROR 0x02
-#define PARITY_ERROR 0x04
-#define FRAMING_ERROR 0x08
-#define BREAK_INTERRUPT 0x10
-#define XMIT_HOLD_EMPTY 0x20
-#define XMIT_EMPTY 0x40
-#define FIFO_ERROR 0x80
-#define RCVR_READY(u) (_LSR(u)&RCVR_DATA_READY)
-#define XMIT_READY(u) (_LSR(u)&XMIT_HOLD_EMPTY)
-
-/* MSR bits */
-#define _RDR 0x01
-#define DELTA_DSR 0x02
-#define DELTA_RI 0x04
-#define DELTA_CD 0x08
-#define _CTS 0x10
-#define _DSR 0x20
-#define _RI 0x40
-#define _CD 0x80
-
-
-/* Compute 16-bit divisor for baudrate generator, with rounding: */
-#define UART_DIVISOR(clock,baud) (((clock)/16 + (baud)/2)/(baud))
-
-/* Prototypes of driver functions */
-extern void uart16550_init( uart_dev_t *u, unsigned baud, unsigned ndata,
- unsigned parity, unsigned nstop );
-extern void uart16550_out( uart_dev_t *u, char c );
-extern char uart16550_in( uart_dev_t *u );
-extern unsigned uart16550_measure_sys_clk( uart_dev_t *u );
-
-#endif /* _UART_16550_H_ */
diff --git a/components/esp32/include/xtensa/udma.h b/components/esp32/include/xtensa/udma.h
deleted file mode 100644
index a5feb77701..0000000000
--- a/components/esp32/include/xtensa/udma.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* Customer ID=11656; Build=0x5f626; Copyright (c) 2005-2014 by Cadence Design Systems, Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of
- * Cadence Design Systems, Inc. They may not be modified, copied, reproduced,
- * distributed, or disclosed to third parties in any manner, medium, or form,
- * in whole or in part, without the prior written consent of Cadence Design
- * Systems Inc.
- */
-#ifndef __UDMA_H__
-#define __UDMA_H__
-
-#include
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Size of the uDMA descriptor */
-#define UDMA_DESC_STRUCT_SIZE 32
-
-/* Request attribute is a bit vector passed to the udma functions - udma_copy,
- * udma_2d_copy, udma_add_descs.
- * Bit 0 : 1 - trigger an interrupt when done, else do nothing
- * Bit 1 : 0 - retry the failed request; abort after programmer specified
- * number of retries. Defaults to abort with no retries.
- * 1 - abort the failed request (after retries) and all pending requests
- */
-#define UDMA_DONE_INTERRUPT 0x1
-#define UDMA_ERROR_ABORT 0x0
-#define UDMA_ERROR_ABORT_ALL 0x2
-
-/* Enum representing various udma error conditions, udma status, and
- * return values
- */
-typedef enum {
- UDMA_OK = 0,
- UDMA_ERROR_QUEUE_FULL = 1,
- UDMA_ERROR_BAD_DESC = 2,
- UDMA_ERROR_DRAM_CROSSING = 3,
- UDMA_ERROR_PIF_ADDR_BUS = 4,
- UDMA_ERROR_PIF_DATA_BUS = 5,
- UDMA_REQ_PENDING = 6,
- UDMA_REQ_DONE = 7,
- UDMA_ERROR_BAD_REQUEST = 8,
- UDMA_ERROR_INVALID_ARG = 11,
- UDMA_ERROR_INIT = 12,
- UDMA_ERROR_INTERNAL = -1
-} udma_status_t;
-
-#ifndef __UDMA_INTERNAL_H__
-/* Opaque structure describing a uDMA descriptor */
-struct udma_desc_struct {
- char _[UDMA_DESC_STRUCT_SIZE];
-} __attribute__ ((aligned (UDMA_DESC_STRUCT_SIZE)));
-#endif
-
-typedef struct udma_desc_struct udma_desc_t;
-
-/* Initialize the udma control structure, the uDMA registers with
- * the descriptor queue addresses, and the uDMA sync and error interrupt
- * handler. This function needs to be invoked prior to using the uDMA.
- *
- * xmp_udma_sync_intr : Processor interrupt number to flag udma done
- * xmp_udma_error_intr : Processor interrupt number to flag udma error
- *
- * Returns UDMA_ERROR_INIT if there was an error during initialization else
- * returns UDMA_OK.
- */
-extern udma_status_t
-udma_init(uint32_t xmp_udma_sync_intr, uint32_t xmp_udma_error_intr);
-
-/* Performs a copy of a linear block of size bytes from the src
- * to the dest address. If the call returns UDMA_OK, status is set to
- * UDMA_REQ_PENDING or UDMA_REQ_DONE. If there is a dma error, the error code,
- * which could be one of UDMA_ERROR_BAD_DESC, UDMA_ERROR_DRAM_CROSSING,
- * UDMA_ERROR_PIF_ADDR_BUS, UDMA_ERROR_PIF_DATA_BUS is returned in the status.
- * Status is set to UDMA_REQ_DONE if the dma completes normally.
- * On completion, the callback function is invoked with the callback_data
- * and status as parameters. Note, the callback is always invoked even if
- * there is a dma error.
- *
- * src : src address of the copy
- * dest : dest address of the copy
- * size : number of bytes to copy
- * callback_data : optional data to be passed to callback_func
- * callback_func : optional callback after copy is done
- * request_attr : attribute defining how to process this request
- * (see description of the request attribute in top of udma.h)
- * status : track status of the copy; this gets also passed
- * as the second argument to the callback_func
- *
- * Returns UDMA_ERROR_QUEUE_FULL if no more requests can be added, else
- * returns UDMA_OK.
- */
-extern udma_status_t
-udma_copy(void *dest,
- void *src,
- size_t size,
- void *callback_data,
- void (*callback_func)(void *, udma_status_t *status),
- uint32_t request_attr,
- udma_status_t *status);
-
-/* Performs a copy of a 2D block of data from the src to the dest
- * address. If the call returns UDMA_OK, status is set to UDMA_REQ_PENDING or
- * UDMA_REQ_DONE. If there is a dma error, the error code,
- * which could be one of UDMA_ERROR_BAD_DESC, UDMA_ERROR_DRAM_CROSSING,
- * UDMA_ERROR_PIF_ADDR_BUS, UDMA_ERROR_PIF_DATA_BUS is returned in the status.
- * Status is set to UDMA_REQ_DONE if the dma completes normally.
- * On completion, the callback function is invoked with the callback_data
- * and status as parameters. Note, the callback is always invoked even if
- * there is a dma error.
- *
- * src : src address of the copy
- * dest : dest address of the copy
- * row_size : number of bytes per row to copy
- * num_rows : number of rows to copy
- * src_pitch : src pitch
- * dest_pitch : dest pitch
- * callback_data : optional data to be passed to callback_func
- * callback_func : optional callback after copy is done
- * request_attr : attribute defining how to process this request
- * (see description of the request attribute in top of udma.h)
- * status : track status of the copy; this gets also passed
- * as the second argument to the callback_func
- *
- * Returns UDMA_ERROR_QUEUE_FULL if no more requests can be added, else
- * returns UDMA_OK.
- */
-extern udma_status_t
-udma_2d_copy(void *dest,
- void *src,
- size_t row_size,
- uint32_t num_rows,
- uint32_t src_pitch,
- uint32_t dest_pitch,
- void *callback_data,
- void (*callback_func)(void *, udma_status_t *status),
- uint32_t request_attr,
- udma_status_t *status);
-
-/* Process requests that are done. Any callbacks associated
- * with the completed requests gets invoked. If there are any errors,
- * the error request is (and any pending request based on the request attribute)
- * cancelled and the error code is returned in the status associated with
- * all such cancelled requests. Callbacks associated with the cancelled
- * requests are also invoked. If all requests terminate normally, the status
- * of the completed requests are set to UDMA_REQ_DONE.
- *
- * Returns void
- */
-extern void
-udma_process_requests();
-
-/* Sets the udma max PIF block size
- *
- * max_block_size : max block size to be set
- *
- * Returns UDMA_ERROR_INVALID_ARG if block_size is > 3, else returns UDMA_OK
- */
-udma_status_t
-udma_set_max_block_size(uint32_t block_size);
-
-/* Sets the udma max outstanding PIF requests
- *
- * max_outstanding : max outstanding PIF requests
- *
- * Returns UDMA_ERROR_INVALID_ARG if max_outstanding is not between 1 and 16
- * else returns UDMA_OK
- */
-udma_status_t
-udma_set_max_outstanding(uint32_t max_outstanding);
-
-/* Initialize a uDMA descriptor using the copy parameters. The descriptor
- * is then queued separately using udma_add_desc
- *
- * src : src address of the copy
- * dest : dest address of the copy
- * row_size : number of bytes per row to copy
- * num_rows : number of rows to copy
- * src_pitch : src pitch
- * dest_pitch : dest pitch
- * notify_with_interrupt : If 1, interrupt when dma is done with this descriptor
- * if 0, do nothing, else undefined
- *
- * Returns void
- */
-extern void
-udma_set_desc(void *src,
- void *dest,
- size_t row_size,
- uint32_t num_rows,
- uint32_t src_pitch,
- uint32_t dest_pitch,
- uint32_t notify_with_interrupt,
- udma_desc_t *desc);
-
-/* Add multiple uDMA descriptors to the descriptor queue. If the call returns
- * UDMA_OK, the status is set to UDMA_REQ_PENDING or UDMA_REQ_DONE.
- * If there is a dma error, the error code, which could be one of
- * UDMA_ERROR_BAD_DESC, UDMA_ERROR_DRAM_CROSSING, UDMA_ERROR_PIF_ADDR_BUS,
- * UDMA_ERROR_PIF_DATA_BUS is returned in the status. Status is set
- * to UDMA_REQ_DONE, if the dma completes normally.
- * On completion, the callback function is invoked with the callback_data
- * and status as parameters. Note, the callback is always invoked even if
- * there is a dma error.
- *
- * desc : descriptors to be added
- * num_desc : number of descriptors to be added
- * callback_data : optional data to be passed to callback_func
- * callback_func : optional callback after copy is done
- * request_attr : attribute defining how to process this request
- * (see description of the request attribute in top of udma.h)
- * Note, bit 0 (for enabling interrupt) is ignored in this call.
- * To interrupt on dma completion, set the
- * notify_with_interrupt parameter when creating descriptors
- * using udma_set_desc.
- * status : track status of the copy; this gets also passed
- * as the second argument to the callback_func
- *
- * Returns UDMA_ERROR_QUEUE_FULL if no more descriptors can be added,
- * UDMA_ERROR_INVALID_ARG if num_descs == 0, else return UDMA_OK
- */
-udma_status_t
-udma_add_descs(udma_desc_t *descs,
- uint32_t num_descs,
- void *callback_data,
- void (*callback_func)(void *, udma_status_t *status),
- uint32_t request_attr,
- udma_status_t *status);
-
-/* Wait for udma copy request to complete. Could spin wait or goto waiti
- * based on the sleep_wait parameter. Once the request is done, the callback
- * associated with this request and any prior completed requests are handled.
- * Error code, if any, is returned in the status s, else s is set to
- * UDMA_REQ_DONE.
- *
- * s : status to wait for
- * sleep_wait : sleep wait if true, else spin waits
- *
- * Returns void
- */
-extern void
-udma_wait_request(volatile udma_status_t *s, uint32_t sleep_wait);
-
-/* Inlined function to set the src, dest address of the descriptor
- *
- * src : src address of the uDMA
- * dest : dest address of the uDMA
- * desc : descriptor to be modified
- *
- * Returns void
- */
-void static inline
-udma_set_desc_addrs(void *src, void *dest, udma_desc_t *desc) {
- uint32_t *d = (uint32_t *)desc;
- *d = (uintptr_t)src;
- *(d+1) = (uintptr_t)dest;
-}
-
-/* Sets the number of retries for a failed dma request
- *
- * max_retries : max number of retries
- *
- * Sets the max number of retries for a failed dma request. The default is 0,
- * i.e, no retries
- */
-void
-udma_set_max_retries(uint32_t max_retries);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __UDMA_H__ */
diff --git a/components/esp32/include/xtensa/xmon.h b/components/esp32/include/xtensa/xmon.h
deleted file mode 100644
index 12a757a2c1..0000000000
--- a/components/esp32/include/xtensa/xmon.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* xmon.h - XMON definitions
- *
- * $Id: //depot/rel/Eaglenest/Xtensa/OS/xmon/xmon.h#3 $
- *
- * Copyright (c) 2001-2013 Tensilica Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __H_XMON
-#define __H_XMON
-
-/* Default GDB packet size */
-#define GDB_PKT_SIZE 4096
-
-/*XMON signals */
-#define XMON_SIGINT 2 /*target was interrupted */
-#define XMON_SIGILL 4 /*illegal instruction */
-#define XMON_SIGTRAP 5 /*general exception */
-#define XMON_SIGSEGV 11 /*page faults */
-
-
-/* Type of log message from XMON to the application */
-typedef enum {
- XMON_LOG,
- XMON_TRACE,
- XMON_ERR,
- XMON_APP,
- XMON_GDB
-} xmon_log_t;
-
-/* Return value type for xmon_proc() (see below) */
-typedef enum {
- XMON_GDB_PEND,
- XMON_GDB_PKT,
- XMON_NOT_GDB
-} xmon_gdb_pkt_t;
-
-#ifdef _cplusplus
-extern "C" {
-#endif
-
-/*
- * THE FOLLOWING ROUTINES ARE USED BY USER
- */
-extern int _xmon_init(char* gdbBuf, int gdbPktSize,
- void(*xlog)(xmon_log_t type, const char* str));
-//Initialize GDB communication and logging to the main app.
-//For the logging to work, xlog function needs to be provided.
-//gdbBuf - pointer to a buffer XMON can use to comm. with GDB
-//gdbPktSize - Size of the allocated buffer for GDB communication.
-//xlog - logger handle.
-
-
-extern void _xmon_close(void);
-//Main application can detach from xmon at any time
-
-
-extern xmon_gdb_pkt_t _xmon_proc(char);
-// Give character to XMON to check if GDB message
-// Application is supposed to accumulate all the
-// character in case the recognition fails and chars
-// have to be sent to the original handler
-// Return: XMON_GDB_PEND - send me more chars
-// XMON_GDB_PKT - GDB message confirmed, C) not
-// XMON_NOT_GDB - not GDB message
-
-
-/*
- * THE FOLLOWING ROUTINES NEED TO BE PROVIDED BY USER
- */
-extern int _xmon_in(); // wait for character from GDB
-extern void _xmon_out(char); // output a character to GDB
-extern int _xmon_flush(void); // flush output characters
-
-#ifdef _cplusplus
-}
-#endif
-
-#endif
diff --git a/components/esp32/include/xtensa/xmp-library.h b/components/esp32/include/xtensa/xmp-library.h
deleted file mode 100644
index 624272077c..0000000000
--- a/components/esp32/include/xtensa/xmp-library.h
+++ /dev/null
@@ -1,789 +0,0 @@
-/* Customer ID=11656; Build=0x5f626; Copyright (c) 2008-2009 by Tensilica Inc. ALL RIGHTS RESERVED.
- These coded instructions, statements, and computer programs are the
- copyrighted works and confidential proprietary information of Tensilica Inc.
- They may not be modified, copied, reproduced, distributed, or disclosed to
- third parties in any manner, medium, or form, in whole or in part, without
- the prior written consent of Tensilica Inc. */
-
-#ifndef _XMP_LIBRARY_H
-#define _XMP_LIBRARY_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include
-#include
-#include
-#if XCHAL_HAVE_RELEASE_SYNC
-#include
-#endif
-#if XCHAL_HAVE_EXTERN_REGS
-#include
-#endif
-#include
-#include
-
-#include "xtensa/system/mpsystem.h"
-
-/*
- W A R N I N G:
-
- xmp library clients should treat all data structures in this file
- as opaque. They are only public to enable users to declare them
- statically.
-*/
-
-
-/* -------------------------------------------------------------------------
- When using XMP on cache-incoherent systems, these macros are helpful
- to ensure that you are not reading stale data, and to ensure that
- the data you write makes it all the way back to main memory.
- */
-
-#if !XCHAL_DCACHE_IS_COHERENT
-#define XMP_WRITE_BACK_ELEMENT(x) xthal_dcache_region_writeback((void *)x, sizeof(*x))
-#define XMP_INVALIDATE_ELEMENT(x) xthal_dcache_region_invalidate((void *)x, sizeof(*x))
-#define XMP_WRITE_BACK_INVALIDATE_ELEMENT(x) xthal_dcache_region_writeback_inv((void *)x, sizeof(*x))
-#define XMP_WRITE_BACK_ARRAY(x) xthal_dcache_region_writeback((void *)x, sizeof(x))
-#define XMP_INVALIDATE_ARRAY(x) xthal_dcache_region_invalidate((void *)x, sizeof(x))
-#define XMP_WRITE_BACK_INVALIDATE_ARRAY(x) xthal_dcache_region_writeback_inv((void *)x, sizeof(x))
-#define XMP_WRITE_BACK_ARRAY_ELEMENTS(x, num_elements) xthal_dcache_region_writeback((void *)x, sizeof(*x) * num_elements)
-#define XMP_INVALIDATE_ARRAY_ELEMENTS(x, num_elements) xthal_dcache_region_invalidate((void *)x, sizeof(*x) * num_elements)
-#define XMP_WRITE_BACK_INVALIDATE_ARRAY_ELEMENTS(x, num_elements) xthal_dcache_region_writeback_inv((void *)x, sizeof(*x) * num_elements)
-#else
-#define XMP_WRITE_BACK_ELEMENT(x)
-#define XMP_INVALIDATE_ELEMENT(x)
-#define XMP_WRITE_BACK_INVALIDATE_ELEMENT(x)
-#define XMP_WRITE_BACK_ARRAY(x)
-#define XMP_INVALIDATE_ARRAY(x)
-#define XMP_WRITE_BACK_INVALIDATE_ARRAY(x)
-#define XMP_WRITE_BACK_ARRAY_ELEMENTS(x, num_elements)
-#define XMP_INVALIDATE_ARRAY_ELEMENTS(x, num_elements)
-#define XMP_WRITE_BACK_INVALIDATE_ARRAY_ELEMENTS(x, num_elements)
-#endif
-
-/* -------------------------------------------------------------------------
- Initialization, error codes, constants and house-keeping
-
- Every core should call xmp_init with the number of cores in the
- system.
-
- xmp_init should be called before you use any global synchronization
- primitive or shared data.
-
- Further, before you use a dynamically allocated synchronization
- primitives, you need to both initialize it by calling the
- xmp_*_init function, and you need to have called xmp_init, which
- sets up interrupt handlers and interrupt routing.
-
- The second parameter sets the interprocessor interrupt
- routing. Passing zero instructs the library to use the default
- routing, which will be suitable for most users.
-
-*/
-
-extern void xmp_init (int num_cores, unsigned int interrupt_routing);
-
-
-/* If you want finer-grained control than that provided by xmp_init,
- you can the functions below individually--however, this is more
- inconvenient and requires greater understanding of the library's
- internals. Don't use them directly unless you have a good reason.
-*/
-
-extern void xmp_unpack_shared (void);
-extern void xmp_route_interrupts (unsigned int routing);
-
-#if XCHAL_HAVE_MP_INTERRUPTS
-extern void xmp_enable_ipi_interrupts (void);
-
-/* Turn off certain things enabled by xmp_init */
-extern void xmp_disable_ipi_interrupts (void);
-#endif
-
-extern void xmp_end (void);
-
-/* Only valid after xmp_init. */
-extern int xmp_num_cores (void);
-
-/* How many cycles should a core wait before rechecking a
- synchronization variable? Higher values will reduce memory
- transactions, but will also result in higher latency in returning
- from synchronization.
-*/
-extern void xmp_spin_wait_set_cycles (unsigned int limit);
-
-/* If you would prefer to provide your own spin wait function,
- to go to sleep, etc. Declare a function of this type, then call
- this function. */
-typedef void (*xmp_spin_wait_function_t)(void);
-extern void xmp_spin_wait_set_function (xmp_spin_wait_function_t func);
-extern void xmp_spin(void);
-
-#define XMP_NO_OWNER 0x07
-#define XMP_MUTEX_DESTROYED 0xFE
-#define XMP_ERROR_FATAL 0xFD
-
-#define XMP_MAX_CORES 0x4
-
-
-static inline unsigned int xmp_prid (void)
-{
-#if XCHAL_HAVE_PRID
- return XT_RSR_PRID() & 0xFF;
-#else
- return 0;
-#endif
-}
-
-
-/* -------------------------------------------------------------------------
- Tracing
-
- A core must set a trace_file if it wants any synchronization
- tracing to occur. Sharing file descriptors among cores is very
- messy, so don't do it. This, unfortunately, means that two cores
- contending for a mutex are not able to trace to the same file.
-
- Any object (except the atomic integer) can have tracing off or on.
-*/
-
-extern void xmp_set_trace_file (FILE * file);
-extern void xmp_trace (const char * fmt, ...);
-
-
-/* -------------------------------------------------------------------------
- Memory Allocation Functions.
-
- These do what you would expect, only from shared memory instead of
- private memory.
-*/
-
-#if XCHAL_DCACHE_IS_COHERENT
-extern void * xmp_malloc (size_t size);
-extern void * xmp_calloc (size_t nmemb, size_t size);
-extern void xmp_free (void * ptr);
-#endif
-extern void * xmp_sbrk(int size);
-
-/* -------------------------------------------------------------------------
- xmp_atomic_int_t
-
- The most basic synchronization primitive in the xmp library.
- Atomic ints are sharable among processors, and even interrupt
- levels on the same processor. However, their semantics are fairly
- rudimentary. All other primitives are based on these, therefore,
- changing this implementation affects all other primitives.
-
-*/
-
-typedef unsigned int xmp_atomic_int_t;
-
-static inline xmp_atomic_int_t
-xmp_coherent_l32ai(xmp_atomic_int_t * address)
-{
- XMP_INVALIDATE_ELEMENT (address);
- return XT_L32AI(address, 0);
-}
-
-static inline void
-xmp_coherent_s32ri(xmp_atomic_int_t value, xmp_atomic_int_t * address)
-{
- XT_S32RI (value, address, 0);
- XMP_WRITE_BACK_ELEMENT (address);
-}
-
-#define XMP_ATOMIC_INT_INITIALIZER(value) (value)
-
-/* xmp_atomic_int_init - Initialize an int prior to use
-
- Nonsynchronizing, Nonblocking
-
- Usage:
- value - initial value
- integer - points to an uninitialized integer
-
- On exit:
- initialized to given value
-
- Errors: none
-*/
-
-static inline void
-xmp_atomic_int_init (xmp_atomic_int_t * integer, int value)
-{
- xmp_coherent_s32ri (value, integer);
-}
-
-
-/* xmp_atomic_int_value - Read the value
-
- Nonsynchronizing, Nonblocking
-
- Usage:
- integer - points to an int
-
- Returns:
- the value
-*/
-
-static inline int
-xmp_atomic_int_value (xmp_atomic_int_t * integer)
-{
- return xmp_coherent_l32ai (integer);
-}
-
-
-/* xmp_atomic_int_conditional_increment - Conditionally increment integer
-
- Synchronizing, nonblocking
-
- Usage:
- integer - points to an initialized integer
- amount - how much to increment
- prev - believed value of the integer
- eg: prev = xmp_atomic_int_value (integer);
- success = xmp_atomic_int_increment (integer, 1, prev);
-
- Returns: current value of integer - user should check if it matches
- the previous value of the integer. If it does, then the update
- was successful.
-
-*/
-
-#define USE_ASSEMBLY_IMPLEMENTATION 0
-
-static inline int
-xmp_atomic_int_conditional_increment (xmp_atomic_int_t * integer, int amount, int prev)
-{
- int val;
- int saved;
-
-#if USE_ASSEMBLY_IMPLEMENTATION
- /* %0 = prev
- %1 = saved
- %2 = atomic integer pointer
- %3 = amount
- */
-
- asm volatile ("wsr.scompare1 %0\n"
- "mov %1, %0\n"
- "add %0, %0, %3\n"
- "s32c1i %0, %2, 0\n"
- : "+&a" (prev), "+&a"(saved) : "a" (integer), "a" (amount));
-
- return prev;
-
-#else
-
- XT_WSR_SCOMPARE1 (prev);
- val = prev + amount;
- saved = val;
- XT_S32C1I (val, integer, 0);
-
- return val;
-#endif
-}
-
-
-/* xmp_atomic_int_increment - Increment integer
-
- Synchronizing, blocking
-
- Usage:
- integer - points to an initialized integer
- amount - how much to increment
-
- Returns: new value of integer
-
-*/
-
-static inline int
-xmp_atomic_int_increment (xmp_atomic_int_t * integer, int amount)
-{
- int val;
- int saved;
-#if USE_ASSEMBLY_IMPLEMENTATION
- /* %0 = val
- %1 = saved
- %2 = atomic integer pointer
- %3 = amount
- */
-
- asm volatile ("l32ai %0, %2, 0\n"
- "1:\n"
- "wsr.scompare1 %0\n"
- "mov %1, %0\n"
- "add %0, %0, %3\n"
- "s32c1i %0, %2, 0\n"
- "bne %0, %1, 1b\n"
- : "+&a" (val), "+&a"(saved) : "a" (integer), "a" (amount));
-#else
- /* Accurately naming "val" is tricky. Sometimes it will be what we
- want to be the new value, but sometimes it contains the value
- that is currently at the location. */
-
- /* Load location's current value */
- val = xmp_coherent_l32ai (integer);
-
- do {
- XT_WSR_SCOMPARE1 (val);
- saved = val;
- /* Change it to what we would like to store there--"new_val" */
- val = val + amount;
- /* Possibly store new_val, but reload location's current value no
- matter what. */
- XT_S32C1I (val, integer, 0);
- if (val != saved)
- xmp_spin();
- } while (val != saved);
-
-#endif
- return val + amount;
-}
-
-
-/* xmp_atomic_int_conditional_set - Set the value of an atomic integer
-
- Synchronizing, nonblocking
-
- Usage:
- integer - points to an initialized integer
- from - believed value of the integer
- eg: prev = xmp_atomic_int_value (integer);
- success = xmp_atomic_int_conditional_set (integer, 1, prev);
- to - new value
-
- Returns: current value of integer - user should check if it matches
- the previous value of the integer. If it does, then the update
- was successful.
-
-*/
-
-static inline int
-xmp_atomic_int_conditional_set (xmp_atomic_int_t * integer, int from, int to)
-{
- int val;
-
- /* Don't even try to update if the integer's value isn't what we
- think it should be. This prevents acquiring this cache-line for
- writing and therefore prevents bus transactions when various
- cores contend. */
- val = xmp_coherent_l32ai(integer);
- if (val == from) {
- XT_WSR_SCOMPARE1 (from);
- val = to;
- /* Possibly store to, but reload location's current value no
- matter what. */
- XT_S32C1I (val, integer, 0);
- }
- return val;
-}
-
-
-/* Macros to implement trivial spin locks. These are very primitive, but
- can be useful when you don't need the higher-overhead synchronization.
-
- To use an xmp_atomic_int_t as a trivial spin lock, you should
- initialize it to zero first.
-*/
-
-#define XMP_SIMPLE_SPINLOCK_ACQUIRE(atomic_int_ptr) \
- { while (xmp_atomic_int_conditional_set (atomic_int_ptr, 0, xmp_prid() + 1) != 0) \
- xmp_spin(); }
-#define XMP_SIMPLE_SPINLOCK_RELEASE(atomic_int_ptr) \
- { while (xmp_atomic_int_conditional_set (atomic_int_ptr, xmp_prid() + 1, 0) != xmp_prid() + 1) \
- xmp_spin(); }
-
-#define XMP_SIMPLE_SPINLOCK_OWNER(atomic_int_ptr) (xmp_atomic_int_value(atomic_int_ptr) - 1)
-
-
-/* -------------------------------------------------------------------------
- xmp_mutex_t - An even higher-level data structure to enforce
- mutual exclusion between cores. A core which waits on a mutex might
- sleep with a waiti and be interrupted by an interrupt.
-
- Mutexes can be normal or recursive. For a normal mutex, a core
- attempting to acquire a mutex it already holds will result in
- deadlock. For a recursive mutex, a core will succeed in acquiring a
- mutex it already holds, and must release it as many times as it
- acquired it.
-
- Mutexes are not sharable between interrupt levels--because
- ownership is tracked by core, not thread.
-
- Like all xmp data structures, an object of type xmp_mutex_t
- should be treated by the programmer as opaque. They are only
- public in this header file to allow them to be declared statically.
-
- For configurations with 16-byte cache lines, this has the most
- frequently used and changed data in the first line.
-
-*/
-
-#if XCHAL_DCACHE_IS_COHERENT
-typedef struct xmp_mutex_t {
- xmp_atomic_int_t qlock;
- unsigned int qhead;
- unsigned int qtail;
- unsigned char queue[XMP_MAX_CORES];
- unsigned short held;
-
- unsigned char owner;
- unsigned char recursive : 1;
- unsigned char trace : 1;
- unsigned char system : 1;
- unsigned char unused : 5;
- const char * name;
-} xmp_mutex_t __attribute__ ((aligned (XMP_MAX_DCACHE_LINESIZE)));
-
-
-#define XMP_MUTEX_INITIALIZER(name) \
- { 0, 0, -1, {XMP_NO_OWNER, XMP_NO_OWNER, XMP_NO_OWNER, XMP_NO_OWNER}, \
- 0, XMP_NO_OWNER, XMP_MUTEX_FLAG_NORMAL, 0, 0, 0, name }
-
-#define XMP_RECURSIVE_MUTEX_INITIALIZER(name) \
- { 0, 0, -1, {XMP_NO_OWNER, XMP_NO_OWNER, XMP_NO_OWNER, XMP_NO_OWNER}, \
- 0, XMP_NO_OWNER, XMP_MUTEX_FLAG_RECURSIVE, 0, 0, 0, name }
-
-#define XMP_MUTEX_FLAG_NORMAL 0
-#define XMP_MUTEX_FLAG_RECURSIVE 1
-
-#define XMP_MUTEX_ACQUIRE_FAILED -1
-#define XMP_MUTEX_ERROR_DESTROY_OWNED -2
-#define XMP_MUTEX_ERROR_NOT_OWNED -3
-#define XMP_MUTEX_ERROR_ALREADY_OWNED -4
-
-/*
- xmp_mutex_init
-
- Nonsynchronizing
- Nonblocking
-
- Usage:
- mutex - points to an uninitialized mutex
- name - name if you want one, NULL if not.
- recursive - use recursive semantices
-
- Returns
- zero on success (always succeeds)
-
-*/
-
-extern int xmp_mutex_init (xmp_mutex_t * mutex,
- const char * name,
- unsigned int recursive);
-
-/*
- int xmp_mutex_destroy (xmp_mutex_t * mutex);
-
- Synchronizing - will fail if mutex is held by anyone -- including
- current processor
- Nonblocking
-
- Usage:
- mutex - points to a mutex
-
- Returns
- zero on success
- non-zero if mutex is held
-*/
-
-extern int xmp_mutex_destroy (xmp_mutex_t * mutex);
-
-
-/*
- xmp_mutex_lock -- Synchronizing
- xmp_mutex_trylock
-
- Usage:
- mutex - points to a mutex
-
- Returns
- zero on success
-*/
-
-extern int xmp_mutex_lock (xmp_mutex_t * mutex);
-extern int xmp_mutex_trylock (xmp_mutex_t * mutex);
-
-
-/*
- xmp_mutex_unlock
-
- Synchronizing
- Nonblocking
-
- Usage:
- mutex - points to a mutex
-
- Returns
- zero on success - mutex is released
- non-zero on failure - mutex is owned by another core
- - prid of processor that does own it
- note that by the time this function
- returns, the owner of the core may
- have changed.
-*/
-
-extern int xmp_mutex_unlock (xmp_mutex_t * mutex);
-
-
-/*
- xmp_mutex_name
-
- Nonsynchronizing
- Nonblocking
-
- Usage:
- mutex - points to a mutex
-
- Returns the name of the given mutex, which may be NULL.
-
-*/
-
-const char * xmp_mutex_name (const xmp_mutex_t * mutex);
-
-
-/*
- xmp_mutex_trace_on
- xmp_mutex_trace_off
-
- Nonsynchronizing
- Nonblocking
-
- Turn off and on tracing for the mutex.
-
- These functions are only present in the debug version of the library.
-*/
-
-extern void xmp_mutex_trace_on (xmp_mutex_t * mutex);
-extern void xmp_mutex_trace_off (xmp_mutex_t * mutex);
-
-
-/* -------------------------------------------------------------------------
- xmp_condition_t
-
- Condition Variables following Mesa semantics.
-
- Condition variables are not sharable among interrupt levels.
-
-*/
-
-
-typedef struct xmp_condition_t {
- unsigned int qhead;
- unsigned int qtail;
- unsigned char queue[XMP_MAX_CORES];
- unsigned int waiting[XMP_MAX_CORES];
-
- unsigned char trace : 1;
- unsigned char unused : 7;
- const char * name;
-} xmp_condition_t __attribute__ ((aligned (XMP_MAX_DCACHE_LINESIZE)));
-
-
-#define XMP_CONDITION_INITIALIZER(name) \
- { 0, -1, {XMP_NO_OWNER, XMP_NO_OWNER, XMP_NO_OWNER, XMP_NO_OWNER}, \
- {0, 0, 0, 0}, 0, 0, name}
-
-
-/* xmp_condition_init - Initialize a condition variable
-
- Nonsynchronizing, Nonblocking
-
- Usage:
- condition - pointer to an xmp_condition_t
-
- On exit:
- condition initialized
-
- Errors: none
-*/
-
-extern int xmp_condition_init (xmp_condition_t * condition,
- const char * name);
-extern int xmp_condition_destroy (xmp_condition_t * condition);
-
-
-/* xmp_condition_wait - Wait for a condition variable
-
- Synchronizing, blocking
-
- Usage:
- condition - pointer to an xmp_condition_t
- mutex - pointer to an xmp_mutex_t already acquired by the calling
- process
-
- Errors: if the mutex isn't held by this core
-*/
-
-extern int xmp_condition_wait (xmp_condition_t * condition,
- xmp_mutex_t * mutex);
-
-/* xmp_condition_signal
-
- - Signal the first (if any) core waiting on a condition variable
-
- You must hold the mutex you passed to xmp_condition_wait before
- calling this function.
-
- Synchronizing, nonblocking
-
- Usage:
- condition - pointer to an xmp_condition_t
-
- Errors: none
-*/
-
-extern int xmp_condition_signal (xmp_condition_t * condition);
-
-
-/* xmp_condition_broadcast
-
- - Signal all cores waiting on a condition variable
-
- Synchronizing, nonblocking
-
- You must hold the mutex you passed to xmp_condition_wait before
- calling this function.
-
- Usage:
- condition - pointer to an xmp_condition_t
-
- Errors: none
-*/
-
-extern int xmp_condition_broadcast (xmp_condition_t * condition);
-
-
-static inline const char * xmp_condition_name (const xmp_condition_t * condition)
-{
- return condition->name;
-}
-
-/*
- xmp_condition_trace_on
- xmp_condition_trace_off
-
- Nonsynchronizing
- Nonblocking
-
- Turn off and on statistics and tracing for the condition. For
- tracing you must also set a trace file for the core.
-
- These functions are only present in the debug-version of the library.
-*/
-
-extern void xmp_condition_trace_on (xmp_condition_t * condition);
-extern void xmp_condition_trace_off (xmp_condition_t * condition);
-
-#endif /* XCHAL_DCACHE_IS_COHERENT */
-
-/* -------------------------------------------------------------------------
- xmp_barrier_t
-
- Classic barriers that stop any core from continuing until a
- specified number of cores reach that point. Once the barrier allows
- cores through, the barrier is reset and will stop cores from
- progressing again.
-
- Barriers are not sharable among interrupt levels.
-
-*/
-
-
-typedef struct xmp_barrier_t
-{
- xmp_atomic_int_t count;
- xmp_atomic_int_t state;
- xmp_atomic_int_t sleeping;
- unsigned short num_cores;
- unsigned short trace : 1;
- unsigned short system : 1;
- const char * name;
-} xmp_barrier_t __attribute__ ((aligned (XMP_MAX_DCACHE_LINESIZE)));
-
-#define XMP_BARRIER_INITIALIZER(number, name) \
- { 0, 0, 0, number, 0, 0, name }
-
-
-/* xmp_barrier_init - Initialize a barrier
-
- Nonsynchronizing, Nonblocking
-
- Usage:
- barrier - pointer to an xmp_barrier_t
- num_cores - number of cores needed to arrive at the
- barrier before any are allowed through
- On exit:
- barrier initialized
-
- Always returns zero.
-
- Errors: none
-*/
-
-extern int xmp_barrier_init (xmp_barrier_t * barrier, int num_cores,
- const char * name);
-
-
-/* xmp_barrier_wait - Wait on a barrier
-
- Nonsynchronizing, Nonblocking
-
- Usage:
- barrier - pointer to an xmp_barrier_t
- On exit:
- Enough cores (as determined at the barrier's initialization)
- have reached the barrier.
-
- Errors: none
-*/
-
-extern int xmp_barrier_wait (xmp_barrier_t * barrier);
-
-
-static inline const char * xmp_barrier_name (const xmp_barrier_t * barrier)
-{
- return barrier->name;
-}
-
-
-/*
- xmp_barrier_trace_on
- xmp_barrier_trace_off
-
- Nonsynchronizing
- Nonblocking
-
- Turn on and off tracing for the barrier. For
- tracing you must also set a trace file for the core.
-
- These functions are only present in the debug-version of the library.
-*/
-
-extern void xmp_barrier_trace_on (xmp_barrier_t * barrier);
-extern void xmp_barrier_trace_off (xmp_barrier_t * barrier);
-
-
-/* -------------------------------------------------------------------------
- Portions of the library that are internal, but belong here for
- convenience.
-*/
-
-extern xmp_atomic_int_t _ResetSync;
-
-static inline void
-xmp_initial_sync (int num_cores)
-{
- xmp_atomic_int_increment (&_ResetSync, 1);
- while (xmp_coherent_l32ai (&_ResetSync) != num_cores)
- xmp_spin ();
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _XMP_LIBRARY_H */
diff --git a/components/esp32/include/xtensa/xos.h b/components/esp32/include/xtensa/xos.h
deleted file mode 100644
index 883a9c975a..0000000000
--- a/components/esp32/include/xtensa/xos.h
+++ /dev/null
@@ -1,524 +0,0 @@
-/** @file */
-
-// xos.h - XOS API interface and data structures visible to user code.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-#ifndef __XOS_H__
-#define __XOS_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#include "xos_types.h"
-
-#include
-#if XCHAL_HAVE_INTERRUPTS
-#include
-#include
-#endif
-
-#include "xos_common.h"
-#include "xos_errors.h"
-#include "xos_regaccess.h"
-
-
-//-----------------------------------------------------------------------------
-// Convert x into a literal string.
-//-----------------------------------------------------------------------------
-#define _XOS_STR(x) __XOS_STR(x)
-#define __XOS_STR(x) #x
-
-
-//-----------------------------------------------------------------------------
-// XOS version.
-//-----------------------------------------------------------------------------
-#define XOS_VERSION_MAJOR 1
-#define XOS_VERSION_MINOR 10
-#define XOS_VERSION_STRING "1.10" ///< XOS version string.
-
-
-//-----------------------------------------------------------------------------
-// Runtime error handling.
-//-----------------------------------------------------------------------------
-
-
-//-----------------------------------------------------------------------------
-///
-/// Reports a fatal error and halts XOS operation, i.e. halts the system. This
-/// function will call a user-registered error handler (if one has been set)
-/// and then halt the system. The user handler may do system-specific things
-/// such as record the error reason in nonvolatile memory etc.
-///
-/// \param errcode Error code. May be any user defined value < 0.
-/// Values >=0 are reserved for use by the system.
-///
-/// \param errmsg Optional text string describing the error.
-///
-/// \return This function does not return.
-///
-//-----------------------------------------------------------------------------
-void
-xos_fatal_error(int32_t errcode, const char * errmsg);
-
-
-#if XOS_DEBUG
-
-// Do not call directly.
-void
-xos_assert(const char * file, int32_t line);
-
-//-----------------------------------------------------------------------------
-///
-/// Check condition and fail if condition expression is false.
-/// In debug builds, an assertion failure will cause a fatal error to be
-/// reported. In non-debug builds, assertions are compiled out.
-///
-/// NOTE: Remember that any code in XOS_ASSERT() statements gets compiled out
-/// for non-debug builds.
-///
-//-----------------------------------------------------------------------------
-
-#define XOS_ASSERT(expr) if ((expr) == 0) xos_assert(__FILE__, __LINE__)
-
-#else
-
-#define XOS_ASSERT(expr)
-
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Interrupt handler function pointer type.
-///
-//-----------------------------------------------------------------------------
-typedef void (XosIntFunc)(void * arg);
-
-//-----------------------------------------------------------------------------
-///
-/// Print handler function pointer type.
-///
-//-----------------------------------------------------------------------------
-typedef int32_t (XosPrintFunc)(void * arg, const char * fmt, ...);
-
-//-----------------------------------------------------------------------------
-///
-/// Fatal error handler function pointer type.
-///
-//-----------------------------------------------------------------------------
-typedef void (XosFatalErrFunc)(int32_t errcode, const char * errmsg);
-
-//-----------------------------------------------------------------------------
-///
-/// Exception handler function pointer type.
-///
-//-----------------------------------------------------------------------------
-typedef void (XosExcHandlerFunc)(XosExcFrame * frame);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Install a user defined exception handler for the specified exception type.
-/// This will override the default XOS exception handler. The handler is a C
-/// function that is passed one parameter -- a pointer to the exception frame.
-/// The exception frame is allocated on the stack of the thread that caused the
-/// exception, and contains saved state and exception information. For details
-/// of the exception frame see the structure XosExcFrame.
-///
-/// \param exc Exception type (number) to override. The exception
-/// numbers are enumerated in .
-///
-/// \param handler Pointer to handler function to be installed.
-/// To revert to the default handler, pass NULL.
-///
-/// \return Returns a pointer to previous handler installed, if any.
-///
-//-----------------------------------------------------------------------------
-XosExcHandlerFunc *
-xos_register_exception_handler(int32_t exc, XosExcHandlerFunc * handler);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Install a user defined fatal error handler. This function will be called if
-/// a fatal error is reported either by user code or by XOS itself. It will be
-/// passed the same arguments that are passed to xos_fatal_error().
-///
-/// The handler need not return. It should make minimal assumptions about the
-/// state of the system. In particular, it should not assume that further XOS
-/// system calls will succeed.
-///
-/// \param handler Pointer to handler function to be installed.
-///
-/// \return Returns a pointer to previous handler installed, if any.
-///
-//-----------------------------------------------------------------------------
-XosFatalErrFunc *
-xos_register_fatal_error_handler(XosFatalErrFunc * handler);
-
-
-#ifdef _XOS_INCLUDE_INTERNAL_
-# include "xos_internal.h"
-#endif
-
-
-#include "xos_thread.h"
-#include "xos_timer.h"
-#include "xos_cond.h"
-#include "xos_event.h"
-#include "xos_mutex.h"
-#include "xos_msgq.h"
-#include "xos_semaphore.h"
-#include "xos_stopwatch.h"
-
-
-//-----------------------------------------------------------------------------
-///
-/// Register a handler function to call when interrupt "num" occurs.
-///
-/// For level-triggered and timer interrupts, the handler function will have
-/// to clear the source of the interrupt before returning, to avoid infinitely
-/// retaking the interrupt. Edge-triggered and software interrupts are
-/// automatically cleared by the OS interrupt dispatcher (see xos_handlers.S).
-///
-/// \param num Xtensa internal interrupt number (0..31). To
-/// refer to a specific external interrupt number
-/// (BInterrupt pin), use HAL macro XCHAL_EXTINTx_NUM
-/// where 'x' is the external number.
-///
-/// \param handler Pointer to handler function.
-///
-/// \param arg Argument passed to handler.
-///
-/// \return Returns XOS_OK if successful, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_register_interrupt_handler(int32_t num, XosIntFunc * handler, void * arg);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Unregister a handler function for interrupt "num". If no handler was
-/// installed, this function will have no effect.
-///
-/// \param num Xtensa internal interrupt number (0..31). To
-/// refer to a specific external interrupt number
-/// (BInterrupt pin), use HAL macro XCHAL_EXTINTx_NUM
-/// where 'x' is the external number.
-///
-/// \return Returns XOS_OK if successful, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_unregister_interrupt_handler(int32_t num);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Register a high priority interrupt handler for interrupt level "level".
-///
-/// Unlike low and medium priority interrupt handlers, high priority handlers
-/// are not installed for a specific interrupt number, but for an interrupt
-/// level. The level must be above XCHAL_EXCM_LEVEL. The handler function must
-/// be written in assembly since C handlers are not supported for levels above
-/// XCHAL_EXCM_LEVEL. The handler function must preserve all registers except
-/// a0, and must return to the dispatcher via a "ret" instruction, not "rfi".
-///
-/// NOTE: This method of dispatch takes a few cycles of overhead. If you wish
-/// to save even these cycles, then you can define your own dispatch function
-/// to override the built-in dispatcher. See xos_handlers.S for more details.
-///
-/// \param level The interrupt level to be handled.
-///
-/// \param handler Pointer to handler function.
-///
-/// \return Returns XOS_OK if successful, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_register_hp_interrupt_handler(int32_t level, void * handler);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Enable a specific interrupt, by interrupt number.
-/// The state (enabled vs. disabled) of individual interrupts is global, i.e.
-/// not associated with any specific thread. Depending on system options and
-/// implementation, this state may be stored in one of two ways:
-/// - directly in the INTENABLE register, or
-/// - in a global variable (this is generally the case when INTENABLE is used
-/// not just to control what interrupts are enabled globally, but also for
-/// software interrupt prioritization within an interrupt level, effectively
-/// providing finer grained levels; in this case XOS takes care to update
-/// INTENABLE whenever either the global enabled-state variable or the
-/// per-thread fine-grained-level variable change).
-/// Thus it is best to never access the INTENABLE register directly.
-///
-/// To modify thread-specific interrupt priority level, use one of:
-/// - xos_set_int_pri_level()
-/// - xos_restore_int_pri_level()
-/// - xos_disable_interrupts()
-/// - xos_restore_interrupts()
-///
-/// NOTE: To refer to a specific external interrupt number (BInterrupt pin),
-/// use HAL macro XCHAL_EXTINTx_NUM where 'x' is the external interrupt
-/// number. For example, to enable external interrupt 3 (BInterrupt[3]),
-/// you can use:
-///
-/// xos_interrupt_enable( XCHAL_EXTINT3_NUM );
-///
-/// \param intnum Interrupt number to enable. Must range between 0-31.
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-void
-xos_interrupt_enable(uint32_t intnum);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Disable a specific individual interrupt, by interrupt number.
-///
-/// This is the counterpart to xos_interrupt_enable(). See the description
-/// of xos_interrupt_enable() for further comments and notes.
-///
-/// \param intnum Interrupt number to disable. Must range between 0-31.
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-void
-xos_interrupt_disable(uint32_t intnum);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get the CPU's current interrupt priority level. Interrupts at or below this
-/// priority level are blocked.
-///
-/// \return Returns the current IPL, ranging from 0 to XCHAL_NUM_INTLEVELS.
-///
-//-----------------------------------------------------------------------------
-static inline uint32_t
-xos_get_int_pri_level(void)
-{
-#if XCHAL_HAVE_INTERRUPTS
- return XT_RSR_PS() & 0xF;
-#else
- return 0;
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set the CPU's interrupt priority level to the specified level, but only if
-/// the current IPL is below the one requested. This function will never cause
-/// the interrupt priority level to be lowered from the current level.
-/// Call this function to block interrupts at or below the specified priority
-/// level.
-///
-/// When setting the IPL temporarily (such as in a critical section), call
-/// xos_set_int_pri_level(), execute the critical code section, and then call
-/// xos_restore_int_pri_level().
-///
-/// The interrupt priority level is part of the thread context, so it is saved
-/// and restored across context switches. To enable and disable individual
-/// interrupts globally, use the functions xos_interrupt_enable() and
-/// xos_interrupt_disable() instead.
-///
-/// NOTE: It is usually not required to disable interrupts at a level higher
-/// than that of the highest priority interrupt that interacts with the OS
-/// (i.e. calls into XOS such that threads may be woken / blocked /
-/// reprioritized / switched, or otherwise access XOS data structures).
-/// In XOS, that maximum level is XOS_MAX_OS_INTLEVEL, which defaults to
-/// XCHAL_EXCM_LEVEL. This may be modified by editing xos_params.h and
-/// rebuilding XOS.
-///
-/// \param level The new interrupt priority level (IPL).
-///
-/// \return Returns a value that can be used to restore the previous
-/// priority level by calling xos_restore_int_pri_level(). This
-/// value should be treated as opaque by application code, and
-/// should be passed unchanged to the restore function.
-///
-//-----------------------------------------------------------------------------
-__attribute__((always_inline))
-static inline uint32_t
-xos_set_int_pri_level(uint32_t level)
-{
-#if XCHAL_HAVE_INTERRUPTS
-#pragma no_reorder
- uint32_t ps = XT_RSR_PS();
-
- if (level > (ps & 0xF)) {
- level = (ps & ~0xF) | level;
- XT_WSR_PS(level);
- XT_RSYNC();
- }
-
- return ps;
-#else
- return 0;
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Restores the CPU to a previously saved interrupt priority level. This level
-/// must have been obtained by calling xos_set_int_pri_level().
-///
-/// \param oldval Return value from xos_set_int_pri_level().
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-__attribute__((always_inline))
-static inline void
-xos_restore_int_pri_level(const uint32_t oldval)
-{
-#if XCHAL_HAVE_INTERRUPTS
-#pragma no_reorder
- XT_WSR_PS(oldval);
- XT_RSYNC();
-#else
- // Nothing
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Disable all interrupts that can interact directly with the OS. This is a
-/// convenience function, shorthand for setting the IPL to XOS_MAX_OS_INTLEVEL.
-///
-/// Returns: A value that can be used to restore the previous priority level
-/// by calling xos_restore_interrupts(). This value should be treated as
-/// opaque by application code, and should be passed unchanged to the restore
-/// function.
-///
-//-----------------------------------------------------------------------------
-static inline uint32_t
-xos_disable_interrupts(void)
-{
- return xos_set_int_pri_level(XOS_MAX_OS_INTLEVEL);
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Restore the CPU's previously saved interrupt status. This is a convenience
-/// function, the counterpart to xos_disable_interrupts().
-///
-/// \return rval Return value from xos_disable_interrupts().
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-static inline void
-xos_restore_interrupts(uint32_t rval)
-{
- xos_restore_int_pri_level(rval);
-}
-
-
-#ifdef _XOS_INCLUDE_INTERNAL_
-
-//-----------------------------------------------------------------------------
-// Enter an OS critical section, i.e. get exclusive access to OS critical
-// state and data structures. Code that manipulates the state of OS objects
-// or modifies internal OS state must call this function first, to ensure
-// that it has exclusive access. On a single-core system, this is equivalent
-// to blocking all interrupts that can interact directly with the OS, i.e.
-// all interrupts at or below XOS_MAX_OS_INTLEVEL. In a multi-core system
-// this is likely to be implemented differently to achieve the same effect.
-//
-// Returns: A value that is to be used to restore the state of the CPU when
-// exiting the critical section. This must be treated as opaque and passed
-// unmodified to xos_critical_exit().
-//
-// NOTE: This function is meant for use in OS code, not in applications.
-//-----------------------------------------------------------------------------
-__attribute__((always_inline))
-static inline uint32_t
-xos_critical_enter(void)
-{
-#if XCHAL_HAVE_INTERRUPTS
- // This function cannot be called by high-level interrupt handlers,
- // i.e. it can never be called with intlevel > XOS_MAX_OS_INTLEVEL.
- // So, we do not need to check current intlevel because we will not
- // ever be lowering it by setting it to XOS_MAX_OS_INTLEVEL.
- // NOTE: sync after RSIL not needed.
- return XT_RSIL(XOS_MAX_OS_INTLEVEL);
-#else
- return 0;
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Exit an OS critical section and restore CPU state. See the documentation
-// for xos_critical_enter().
-//
-// cflags Return value from xos_critical_enter().
-// Must be treated as an opaque value.
-//
-// Returns: Nothing.
-//
-// NOTE: This function is meant for use in OS code, not in applications.
-//-----------------------------------------------------------------------------
-__attribute__((always_inline))
-static inline void
-xos_critical_exit(uint32_t cflags)
-{
- xos_restore_int_pri_level(cflags);
-}
-
-#endif // _XOS_INCLUDE_INTERNAL_
-
-
-// This file uses things defined above
-#include "xos_syslog.h"
-
-
-// Misc
-
-//-----------------------------------------------------------------------------
-// Helper function to list all threads in system. Useful for debug.
-//-----------------------------------------------------------------------------
-void
-xos_display_threads(void * arg, XosPrintFunc * print_fn);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __XOS_H__
-
diff --git a/components/esp32/include/xtensa/xos_common.h b/components/esp32/include/xtensa/xos_common.h
deleted file mode 100644
index 647cb7f457..0000000000
--- a/components/esp32/include/xtensa/xos_common.h
+++ /dev/null
@@ -1,362 +0,0 @@
-
-// xos_common.h - Macros and definitions common to C and assembly code.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-#ifndef __XOS_COMMON_H__
-#define __XOS_COMMON_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#include
-#include
-#include
-
-#include "xos_params.h"
-
-
-//-----------------------------------------------------------------------------
-// Macros that help define structures for both C and assembler.
-// These are somewhat different from the XTOS version in xtruntime-frames.h.
-//-----------------------------------------------------------------------------
-#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
-
-#define STRUCT_BEGIN .pushsection .text; .struct 0
-#define STRUCT_FIELD(ctype,size,asname,name) asname: .space size
-#define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space (size)*(n)
-#define STRUCT_END(sname) sname##Size:; .popsection
-
-#else
-
-#define STRUCT_BEGIN typedef struct {
-#define STRUCT_FIELD(ctype,size,asname,name) ctype name;
-#define STRUCT_AFIELD(ctype,size,asname,name,n) ctype name[n];
-#define STRUCT_END(sname) } sname;
-
-#endif //_ASMLANGUAGE || __ASSEMBLER__
-
-
-//-----------------------------------------------------------------------------
-// Offsets relative to xos_globals.
-//-----------------------------------------------------------------------------
-#define XOS_INTLEVEL_MASK 0 // offset to the level mask
-#define XOS_INTENABLE_MASK 4 // offset to the enable mask
-#define XOS_CURR_THREADPTR 8 // offset to the current thread ptr
-#define XOS_NEXT_THREADPTR 12 // offset to the next thread ptr
-#define XOS_INTERRUPT_TABLE 16 // offset to the interrupt table
-
-
-//-----------------------------------------------------------------------------
-// Offsets for xos_interrupt_table[] entries.
-//-----------------------------------------------------------------------------
-#define XOS_INTTAB_HANDLER (XOS_INTERRUPT_TABLE+0) // ofs to interrupt handler
-#define XOS_INTTAB_ARG (XOS_INTERRUPT_TABLE+4) // ofs to interrupt handler arg
-#define XOS_INTTAB_PS (XOS_INTERRUPT_TABLE+8) // (hwpri) PS for interrupt level
-#define XOS_INTTAB_LEVEL (XOS_INTERRUPT_TABLE+8) // (swpri) interrupt level (1..7)
-#define XOS_INTTAB_PRI (XOS_INTERRUPT_TABLE+9) // (swpri) interrupt priority (0..255)
-#define XOS_INTTAB_PRIMASK (XOS_INTERRUPT_TABLE+12) // (swpri) mask of higher pri. interrupts
-
-
-//-----------------------------------------------------------------------------
-// Exception/interrupt stack frame layout for a pre-empted thread
-// tcb->resume_fn == &xos_resume_preempted_thread).
-// Pointed to by thread->esf. Located just below thread's current stack ptr.
-// Thread's a1 == thread->esf + XosExcFrameSize.
-// NOTE: exception frame size is a multiple of 16.
-//-----------------------------------------------------------------------------
-STRUCT_BEGIN
-STRUCT_AFIELD(long,4,FRAME_AREG,areg, 12) // a4-a15 (offsets 0 thru 44)
- // (a1 is computed, a0,a2-a3 are in s32e range of a1)
-//#if XCHAL_HAVE_LOOPS
-STRUCT_FIELD (long,4,FRAME_LBEG,lbeg)
-STRUCT_FIELD (long,4,FRAME_LEND,lend)
-STRUCT_FIELD (long,4,FRAME_LCOUNT,lcount)
-//#endif
-//#if XCHAL_HAVE_MAC16
-STRUCT_FIELD (long,4,FRAME_ACCLO,acclo)
-STRUCT_FIELD (char,1,FRAME_ACCHI,acchi)
-//#endif
-STRUCT_FIELD (char,1,FRAME_SAR,sar)
-STRUCT_FIELD (short,2,FRAME_PAD0,pad0) // unused
-STRUCT_FIELD (long,4,FRAME_EXCCAUSE,exccause)
-STRUCT_FIELD (long,4,FRAME_EXCVADDR,excvaddr)
-STRUCT_FIELD (long,4,FRAME_PAD1,pad1) // unused -- pad to make multiple of 16 bytes
-STRUCT_FIELD (long,4,FRAME_PAD2,pad2)
-STRUCT_FIELD (long,4,FRAME_PS,ps) // (XOS_FRAME_SIZE-44) in S32E range of end
-STRUCT_FIELD (long,4,FRAME_PC,pc) // (XOS_FRAME_SIZE-40) in S32E range of end
-STRUCT_FIELD (long,4,FRAME_A0,a0)
-STRUCT_FIELD (long,4,FRAME_A2,a2) // (XOS_FRAME_SIZE-32) in S32E range of end
-STRUCT_FIELD (long,4,FRAME_A3,a3) // (XOS_FRAME_SIZE-28) in S32E range of end
-STRUCT_FIELD (long,4,FRAME_LEVELMASK,levelmask) //
-STRUCT_FIELD (long,4,FRAME_NESTCHAIN,nestchain) // nested C function call chain ptr
-// Caller's a0-a3 save area below SP. These fields MUST be the last ones in the
-// struct so that they are guaranteed to be just under the original SP (before
-// we allocate the exception frame).
-STRUCT_AFIELD (long,4,FRAME_CWINSAVE,cwinsave, 4) // (XOS_FRAME_SIZE-16)
-STRUCT_END(XosExcFrame) // NOTE: exception frame size is 128
-
-#define FRAME_AR(x) (FRAME_AREG + x*4 - 16)
-
-#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
-#define XOS_FRAME_SIZE XosExcFrameSize
-#else
-#define XOS_FRAME_SIZE sizeof(XosExcFrame)
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Stack frame layout for a cooperatively switched out thread
-// (tcb->resume_fn == &xos_resume_cooperative_thread).
-// Pointed to by thread->esf. This is a function frame.
-// Thread's a1 == thread->esf.
-//-----------------------------------------------------------------------------
-STRUCT_BEGIN
-STRUCT_FIELD (long,4,CFRAME_A0,a0) // return PC
-STRUCT_FIELD (long,4,CFRAME_LEVELMASK,levelmask)
-STRUCT_FIELD (long,4,CFRAME_PS,ps)
-#ifdef __XTENSA_CALL0_ABI__
-STRUCT_FIELD (long,4,CFRAME_PAD0,pad0)
-STRUCT_AFIELD(long,4,CFRAME_AREG,areg,4) // callee-saved regs a12-a15
-#endif
-STRUCT_END(XosCoopFrame)
-
-
-//-----------------------------------------------------------------------------
-// Offsets into thread control block (must match xos_thread.h !!)
-//-----------------------------------------------------------------------------
-#define TCB_RESUME_FN 12 // ptr to thread resume asm sequence
-#define TCB_STACK_ESF 16 // saved stack ptr (actually, ptr to ESF)
-#define TCB_TIE_SAVE 20 // ptr to TIE save area
-#define TCB_RETVALUE 24 // ptr to xos_block return value
-#define TCB_STACK_END 36 // ptr to end of stack (thread's initial stack ptr)
-#define TCB_STARTUP_ENTRY 40 // ptr to thread entry function
-#define TCB_STARTUP_ARG 44 // ptr to thread entry function's arg
-#define TCB_READY 48 // thread ready state (1 byte)
-#define TCB_CLIB_PTR 108 // thread C lib context pointer
-
-#define TCB_RESUME_CCOUNT 116 // cycle count at last resume
-#define TCB_CYCLE_COUNT 120 // number of cycles consumed
-#define TCB_NORMAL_RESUMES 128 // number of cooperative/restart thread resumes
-#define TCB_PREEMPT_RESUMES 132 // number of pre-emptive thread resumes
-
-
-//-----------------------------------------------------------------------------
-// Coprocessor state handling:
-// The coprocessor state save area is allocated on the thread stack. The stack
-// must be sized appropriately. Threads that do not use coprocessors need not
-// allocate the storage area.
-//
-// Along with the save area for each coprocessor, two bitmasks with flags per
-// coprocessor (laid out as in the CPENABLE reg) help manage context switching
-// coprocessors as efficiently as possible:
-//
-// XT_CPENABLE
-// The contents of a non-running thread's CPENABLE register.
-// It represents the coprocessors owned (and whose state is still needed)
-// by the thread. When a thread is preempted, its CPENABLE is saved here.
-// When a thread solicits a context switch, its CPENABLE is cleared - the
-// compiler has saved the (caller-saved) coprocessor state if needed.
-// When a non-running thread loses ownership of a CP, its bit is cleared.
-// When a thread runs, it's XT_CPENABLE is loaded into the CPENABLE reg.
-// Avoids coprocessor exceptions when no change of ownership is needed.
-//
-// XT_CPSTORED
-// A bitmask with the same layout as CPENABLE, a bit per coprocessor.
-// Indicates whether the state of each coprocessor is saved in the state
-// save area. When a thread enters the kernel, only the state of coprocs
-// still enabled in CPENABLE is saved. When the coprocessor exception
-// handler assigns ownership of a coprocessor to a thread, it restores
-// the saved state only if this bit is set, and clears this bit.
-//
-// XT_CP_CS_ST
-// A bitmask with the same layout as CPENABLE, a bit per co-processor.
-// Indicates whether callee-saved state is saved in the state save area.
-// Callee-saved state is saved by itself on a solicited context switch,
-// and restored when needed by the coprocessor exception handler.
-// Unsolicited switches will cause the entire coprocessor to be saved
-// when necessary.
-//
-// XT_NCP_ASA
-// Pointer to aligned save area for non-CP state. This is always filled
-// in, even if there is no non-CP state to be saved. If there is no state
-// to be saved then no space is actually allocated and this pointer is
-// not used.
-//
-// XT_CP_ASA
-// Pointer to aligned save area for coprocessor state. This is filled in
-// only if coprocessor state is to be saved for the thread. Allows it to be
-// aligned more than the overall save area (which might be stack-aligned
-// or TCB-aligned). Especially relevant for Xtensa cores configured with a
-// very large data path that requires alignment greater than 16 bytes (ABI
-// stack alignment).
-//-----------------------------------------------------------------------------
-
-#define ALIGNUP(n, val) (((val) + (n)-1) & -(n))
-
-// Offsets of each coprocessor save area within the 'aligned save area'.
-// The non-CP TIE state save area is at offset 0, so that it does not
-// move around if some or all coprocessors are not to be saved.
-
-#define XT_NCP_SA 0
-#define XT_CP0_SA ALIGNUP(XCHAL_CP0_SA_ALIGN, XT_NCP_SA + XCHAL_NCP_SA_SIZE)
-#define XT_CP1_SA ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE)
-#define XT_CP2_SA ALIGNUP(XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE)
-#define XT_CP3_SA ALIGNUP(XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE)
-#define XT_CP4_SA ALIGNUP(XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE)
-#define XT_CP5_SA ALIGNUP(XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE)
-#define XT_CP6_SA ALIGNUP(XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE)
-#define XT_CP7_SA ALIGNUP(XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE)
-
-#define XT_TOT_SA_SIZE ALIGNUP(16, XT_CP7_SA + XCHAL_CP7_SA_SIZE)
-#define XT_NCP_SA_SIZE XCHAL_NCP_SA_SIZE
-
-// Offsets within the overall save area
-
-#define XT_CPENABLE 0 // (2 bytes) coprocessors active for this thread
-#define XT_CPSTORED 2 // (2 bytes) coprocessors saved for this thread
-#define XT_CP_CS_ST 4 // (2 bytes) coprocessor callee-saved regs for this thread
-#define XT_NCP_ASA 8 // (4 bytes) ptr to aligned save area for nonCP state
-#define XT_CP_ASA 12 // (4 bytes) ptr to aligned save area for CP state
-
-// Overall size allows for dynamic alignment, make sure multiple of 4 bytes.
-// XT_CP_SIZE - total space needed for all coprocessors + nonCP state + hdr
-// XT_NCP_SIZE - total space needed for nonCP state + hdr
-
-#define XT_CP_SIZE ALIGNUP(4, (16 + XT_TOT_SA_SIZE + XCHAL_TOTAL_SA_ALIGN))
-#define XT_NCP_SIZE ALIGNUP(4, (16 + XT_NCP_SA_SIZE + XCHAL_TOTAL_SA_ALIGN))
-
-
-//-----------------------------------------------------------------------------
-// Stack size computation.
-//
-// XOS_STACK_MIN_SIZE
-// The minimum recommended stack size for any XOS thread. If you want to
-// use a stack size smaller than this, you will have to verify that the
-// smaller size will work under all operating conditions.
-//
-// XOS_STACK_MIN_SIZE_NO_CP
-// The minimum recommended atack size for threads that will not use any
-// coprocessor resources. No coprocessor state will be saved/restored
-// for these threads. Non-CP TIE state will still be saved/restored.
-// These threads must be created with the flag XOS_THREAD_NO_CP.
-//
-// XOS_STACK_EXTRA
-// The amount of stack space used by the system to:
-// - save coprocessor state
-// - save non-coprocessor TIE state
-// - allocate an interrupt/exception frame
-//
-// XOS_STACK_EXTRA_NO_CP
-// The amount of stack space used by the system to:
-// - save non-coprocessor TIE state
-// - allocate an interrupt/exception frame
-//-----------------------------------------------------------------------------
-
-#define XOS_STACK_EXTRA (XOS_FRAME_SIZE + XT_CP_SIZE)
-#define XOS_STACK_EXTRA_NO_CP (XOS_FRAME_SIZE + XT_NCP_SIZE)
-
-#ifdef __XTENSA_CALL0_ABI__
-#define XOS_STACK_MIN_SIZE (XOS_STACK_EXTRA + 0x180)
-#define XOS_STACK_MIN_SIZE_NO_CP (XOS_STACK_EXTRA_NO_CP + 0x180)
-#else
-#define XOS_STACK_MIN_SIZE (XOS_STACK_EXTRA + 0x200)
-#define XOS_STACK_MIN_SIZE_NO_CP (XOS_STACK_EXTRA_NO_CP + 0x200)
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Items related to C library thread safety.
-//-----------------------------------------------------------------------------
-#if XOS_OPT_THREAD_SAFE_CLIB
-
-#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
- #if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
- #include
- #endif
- #define CLIB_THREAD_STRUCT struct _reent xclib_reent
- #define GLOBAL_CLIB_PTR _reent_ptr
-#elif XSHAL_CLIB == XTHAL_CLIB_NEWLIB
- #if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
- #include
- #endif
- #define CLIB_THREAD_STRUCT struct _reent newlib_reent
- #define GLOBAL_CLIB_PTR _impure_ptr
-#else
- #error The selected C runtime library is not thread safe.
-#endif
-
-#endif // XOS_OPT_THREAD_SAFE_CLIB
-
-
-//-----------------------------------------------------------------------------
-// Check (MAX_OS_INTLEVEL,EXCM_LEVEL)
-//-----------------------------------------------------------------------------
-#if XOS_MAX_OS_INTLEVEL >= XCHAL_EXCM_LEVEL
-# define XOS_MAX_OSEXCM_LEVEL XOS_MAX_OS_INTLEVEL
-#else
-# warning "XOS_MAX_OS_INTLEVEL was set below XCHAL_EXCM_LEVEL: this was never tested"
-# define XOS_MAX_OSEXCM_LEVEL XCHAL_EXCM_LEVEL
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Detect if in interrupt context.
-//-----------------------------------------------------------------------------
-#if XCHAL_HAVE_INTERRUPTS
-#define INTERRUPT_CONTEXT ((XT_RSR_PS() & PS_UM) == 0)
-#else
-#define INTERRUPT_CONTEXT 0
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Xtensa tools version.
-//-----------------------------------------------------------------------------
-#if defined __XCC__
-#define XTTOOLS_VERSION (__XCC__ + __XCC_MINOR__)
-#else
-#define XTTOOLS_VERSION (0)
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Erratum workarounds.
-//-----------------------------------------------------------------------------
-
-// Erratum 487 fix is available in version RF.3 onwards and RG.2 onwards.
-#if ((__XCC__ == 11000) && (__XCC_MINOR__ >= 3)) || (XTTOOLS_VERSION >= 12002)
-#define HWERR_487_FIX hw_erratum_487_fix
-#else
-#define HWERR_487_FIX
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __XOS_COMMON_H__
-
diff --git a/components/esp32/include/xtensa/xos_cond.h b/components/esp32/include/xtensa/xos_cond.h
deleted file mode 100644
index 8116947d33..0000000000
--- a/components/esp32/include/xtensa/xos_cond.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/** @file */
-
-// xos_cond.h - XOS condition variables API interface and data structures.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// NOTE: Do not include this file directly in your application. Including
-// xos.h will automatically include this file.
-
-#ifndef __XOS_COND_H__
-#define __XOS_COND_H__
-
-#include "xos_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-//-----------------------------------------------------------------------------
-//
-// Function pointer type for condition callbacks (defined in xos_thread.h)
-//
-// typedef int32_t (XosCondFunc)(void * arg, int32_t sig_value, XosThread * thread);
-//
-//-----------------------------------------------------------------------------
-
-
-//-----------------------------------------------------------------------------
-///
-/// Condition object.
-///
-//-----------------------------------------------------------------------------
-typedef struct XosCond {
- XosThreadQueue queue; ///< Queue of waiters.
-#if XOS_COND_DEBUG
- uint32_t sig; // Signature indicates valid object.
-#endif
-} XosCond;
-
-
-//-----------------------------------------------------------------------------
-///
-/// Initialize a condition object before first use. The object must be
-/// allocated by the caller.
-///
-/// \param cond Pointer to condition object.
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-void
-xos_cond_create(XosCond * cond);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Destroy a condition object. Must have been previously created by calling
-/// xos_cond_create().
-///
-/// \param cond Pointer to condition object.
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-void
-xos_cond_delete(XosCond * cond);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Wait on a condition: block until the condition is satisfied. The condition
-/// is satisfied when xos_cond_signal() is called on this condition *and* the
-/// condition callback function returns non-zero. If there is no callback
-/// function, then the condition is automatically satisfied.
-///
-/// The condition structure must have been initialized before first use by
-/// calling xos_cond_create().
-///
-/// \param cond Pointer to condition object.
-///
-/// \param cond_fn Pointer to a function, called by xos_cond_signal(),
-/// that should return non-zero if this thread is to
-/// be resumed. The function is invoked as:
-/// `(*cond_fn)(cond_arg, sig_value)`.
-///
-/// \param cond_arg Argument passed to cond_fn.
-///
-/// \return Returns the value passed to xos_cond_signal().
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_cond_wait(XosCond * cond, XosCondFunc * cond_fn, void * cond_arg);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Trigger the condition: wake all threads waiting on the condition, if their
-/// condition function evaluates to true (non-zero). If there is no condition
-/// function for a thread then it is automatically awakened.
-///
-/// The condition structure must have been initialized before first use by
-/// calling xos_cond_create().
-///
-/// \param cond Pointer to condition object.
-///
-/// \param sig_value Value passed to all waiters, returned by
-/// xos_cond_wait().
-///
-/// \return Returns the number of waiting threads that were resumed.
-///
-/// NOTE: Signaling a condition that has no waiters has no effect on it, and
-/// the signal is not remembered. Any thread that waits on it later must be
-/// woken by another call to xos_cond_signal().
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_cond_signal(XosCond * cond, int32_t sig_value);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __XOS_COND_H__
-
diff --git a/components/esp32/include/xtensa/xos_errors.h b/components/esp32/include/xtensa/xos_errors.h
deleted file mode 100644
index 790cdde3bd..0000000000
--- a/components/esp32/include/xtensa/xos_errors.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/** @file */
-
-// xos_errors.h - XOS error codes.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// NOTE: Do not include this file directly in your application. Including
-// xos.h will automatically include this file.
-
-
-#ifndef __XOS_ERRORS_H__
-#define __XOS_ERRORS_H__
-
-#include "xos_types.h"
-
-
-#define _XOS_ERR_FIRST (-65536)
-#define _XOS_ERR_LAST (-1)
-
-
-//-----------------------------------------------------------------------------
-///
-/// List of XOS error codes. All error codes are negative integers, except for
-/// XOS_OK which is zero.
-/// XOS error codes occupy the range from -65536 up to -1.
-/// The function IS_XOS_ERRCODE() can be used to check if a value lies within
-/// the error code range.
-///
-//-----------------------------------------------------------------------------
-typedef enum xos_err_t {
- XOS_OK = 0,
-
- XOS_ERR_NOT_FOUND = _XOS_ERR_FIRST, ///< Object not found
- XOS_ERR_INVALID_PARAMETER, ///< Function parameter is invalid
- XOS_ERR_LIMIT, ///< Limit exceeded
- XOS_ERR_NOT_OWNED, ///< Object not owned by caller
- XOS_ERR_MUTEX_LOCKED, ///< Mutex is already locked
- XOS_ERR_MUTEX_NOT_OWNED, ///< Mutex not owned by caller
- XOS_ERR_MUTEX_ALREADY_OWNED, ///< Mutex already owned by caller
- XOS_ERR_MUTEX_DELETE, ///< Mutex being waited on has been deleted
- XOS_ERR_COND_DELETE, ///< Condition being waited on has been deleted
- XOS_ERR_SEM_DELETE, ///< Semaphore being waited on has been deleted
- XOS_ERR_SEM_BUSY, ///< Semaphore is not available
- XOS_ERR_EVENT_DELETE, ///< Event being waited on has been deleted
- XOS_ERR_MSGQ_FULL, ///< Message queue is full
- XOS_ERR_MSGQ_EMPTY, ///< Message queue is empty
- XOS_ERR_MSGQ_DELETE, ///< Message queue being waited on has been deleted
- XOS_ERR_TIMER_DELETE, ///< Timer being waited on has been deleted
- XOS_ERR_CONTAINER_NOT_RTC, ///< Containing thread not of RTC type
- XOS_ERR_CONTAINER_NOT_SAME_PRI, ///< Containing thread not at same priority
- XOS_ERR_STACK_TOO_SMALL, ///< Thread stack is too small
- XOS_ERR_CONTAINER_ILLEGAL, ///< Illegal container thread
- XOS_ERR_ILLEGAL_OPERATION, ///< This operation is not allowed
- XOS_ERR_THREAD_EXITED, ///< The thread has already exited
- XOS_ERR_NO_TIMER, ///< No suitable timer found
- XOS_ERR_FEATURE_NOT_PRESENT, ///< This feature is disabled or not implemented
- XOS_ERR_TIMEOUT, ///< Wait timed out
-
- XOS_ERR_UNHANDLED_INTERRUPT, ///< No handler for interrupt
- XOS_ERR_UNHANDLED_EXCEPTION, ///< No handler for exception
- XOS_ERR_INTERRUPT_CONTEXT, ///< Operation is illegal in interrupt context
- XOS_ERR_THREAD_BLOCKED, ///< Thread already blocked
- XOS_ERR_ASSERT_FAILED, ///< Runtime assertion failure
- XOS_ERR_CLIB_ERR, ///< Error in C library thread safety module
- XOS_ERR_INTERNAL_ERROR, ///< XOS internal error
-
- XOS_ERR_LAST = _XOS_ERR_LAST,
-} xos_err_t;
-
-
-//-----------------------------------------------------------------------------
-///
-/// Check if a value is a valid XOS error code.
-///
-/// \param val Value to check
-///
-/// \return Returns nonzero if 'val' is in the XOS error code range.
-///
-//-----------------------------------------------------------------------------
-static inline int32_t
-IS_XOS_ERRCODE(xos_err_t val)
-{
- return ((val >= _XOS_ERR_FIRST) && (val <= _XOS_ERR_LAST));
-}
-
-
-#endif // __XOS_ERRORS_H__
-
diff --git a/components/esp32/include/xtensa/xos_event.h b/components/esp32/include/xtensa/xos_event.h
deleted file mode 100644
index 43219a2478..0000000000
--- a/components/esp32/include/xtensa/xos_event.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/** @file */
-
-// xos_event.h - XOS Event API interface and data structures.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// NOTE: Do not include this file directly in your application. Including
-// xos.h will automatically include this file.
-
-#ifndef __XOS_EVENT_H__
-#define __XOS_EVENT_H__
-
-#include "xos_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Defines.
-//-----------------------------------------------------------------------------
-#define XOS_EVENT_BITS_ALL 0xFFFFFFFF
-#define XOS_EVENT_BITS_NONE 0
-
-
-//-----------------------------------------------------------------------------
-// Event flags.
-//-----------------------------------------------------------------------------
-
-
-//-----------------------------------------------------------------------------
-///
-/// Event object.
-///
-//-----------------------------------------------------------------------------
-typedef struct XosEvent {
- XosThreadQueue waitq; ///< Queue of waiters.
- uint32_t bits; ///< Event bits
- uint32_t mask; ///< Specifies which bits are valid
- uint16_t flags; ///< Properties.
- uint16_t pad; ///< Padding
-#if XOS_EVENT_DEBUG
- uint32_t sig; // Valid signature indicates inited.
-#endif
-} XosEvent;
-
-
-//-----------------------------------------------------------------------------
-///
-/// Initialize an event object before first use.
-///
-/// \param event Pointer to event object.
-///
-/// \param mask Mask of active bits. Only these bits can be signaled.
-///
-/// \param flags Creation flags (currently ignored, should be zero).
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-void
-xos_event_create(XosEvent * event, uint32_t mask, uint32_t flags);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Destroy an event object. Must have been previously created by calling
-/// xos_event_create().
-///
-/// \param event Pointer to event object.
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-void
-xos_event_delete(XosEvent * event);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set the specified bits in the specified event. Propagates the bit states
-/// to all waiting threads and wakes them if needed.
-///
-/// \param event Pointer to event object.
-///
-/// \param bits Mask of bits to set. Bits not set in the mask
-/// will not be modified by this call. To set all
-/// the bits in the event, use the constant
-/// XOS_EVENT_BITS_ALL.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_event_set(XosEvent * event, uint32_t bits);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Clear the specified bits in the specified event. Propagates the bit states
-/// to all waiting threads and wakes them if needed.
-///
-/// \param event Pointer to event object.
-///
-/// \param bits Mask of bits to clear. Every bit that is set in
-/// the mask will be cleared from the event. Bits
-/// not set in the mask will not be modified by this
-/// call. To clear all the bits in an event use the
-/// constant XOS_EVENT_BITS_ALL.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_event_clear(XosEvent * event, uint32_t bits);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Clear and set the specified bits in the specified event. The two steps are
-/// combined into one update, so this is faster than calling xos_event_clear()
-/// and xos_event_set() separately. Only one update is sent out to waiting
-/// threads.
-///
-/// \param event Pointer to event object.
-///
-/// \param clr_bits Mask of bits to clear. The clear operation
-/// happens before the set operation.
-///
-/// \param set_bits Mask of bits to set.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_event_clear_and_set(XosEvent * event, uint32_t clr_bits, uint32_t set_bits);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get the current state of the event object. This is a snapshot of the state
-/// of the event at this time.
-///
-/// \param event Pointer to event object.
-///
-/// \param pstate Pointer to a uint32_t variable where the state
-/// will be returned.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_event_get(XosEvent * event, uint32_t * pstate);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Wait until all the specified bits in the wait mask become set in the given
-/// event object.
-///
-/// \param event Pointer to event object.
-///
-/// \param bits Mask of bits to test.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_event_wait_all(XosEvent * event, uint32_t bits);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Wait until all the specified bits in the wait mask become set in the given
-/// event object, or the timeout expires.
-///
-/// \param event Pointer to event object.
-///
-/// \param bits Mask of bits to test.
-///
-/// \param to_cycles Timeout in cycles. Convert from time to cycles
-/// using the helper functions provided in xos_timer.
-/// A value of zero indicates no timeout.
-///
-/// \return Returns XOS_OK on success, XOS_ERR_TIMEOUT on timeout, else
-/// error code.
-///
-/// NOTE: If XOS_OPT_WAIT_TIMEOUT is not enabled, then the timeout value is
-/// ignored, and no timeout will occur.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_event_wait_all_timeout(XosEvent * event, uint32_t bits, uint64_t to_cycles);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Wait until any of the specified bits in the wait mask become set in the
-/// given event object.
-///
-/// \param event Pointer to event object.
-///
-/// \param bits Mask of bits to test.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_event_wait_any(XosEvent * event, uint32_t bits);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Wait until any of the specified bits in the wait mask become set in the
-/// event object, or the timeout expires.
-///
-/// \param event Pointer to event object.
-///
-/// \param bits Mask of bits to test.
-///
-/// \param to_cycles Timeout in cycles. Convert from time to cycles
-/// using the helper functions provided in xos_timer.
-/// A value of zero indicates no timeout.
-///
-/// \return Returns XOS_OK on success, XOS_ERR_TIMEOUT on timeout, else
-/// error code.
-///
-/// NOTE: If XOS_OPT_WAIT_TIMEOUT is not enabled, then the timeout value is
-/// ignored, and no timeout will occur.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_event_wait_any_timeout(XosEvent * event, uint32_t bits, uint64_t to_cycles);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Atomically set a specified group of bits, then wait for another specified
-/// group of bits to become set.
-///
-/// \param event Pointer to event object.
-///
-/// \param set_bits Group of bits to set.
-///
-/// \param wait_bits Group of bits to wait on. All the bits in the
-/// group will have to get set before the wait is
-/// satisfied.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_event_set_and_wait(XosEvent * event, uint32_t set_bits, uint32_t wait_bits);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __XOS_EVENT_H__
-
diff --git a/components/esp32/include/xtensa/xos_internal.h b/components/esp32/include/xtensa/xos_internal.h
deleted file mode 100644
index 5b8c8b4662..0000000000
--- a/components/esp32/include/xtensa/xos_internal.h
+++ /dev/null
@@ -1,120 +0,0 @@
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-#ifndef __XOS_INTERNAL_H__
-#define __XOS_INTERNAL_H__
-
-#if !defined(__XOS_H__) || !defined(_XOS_INCLUDE_INTERNAL_)
- #error "xos_internal.h must be included by defining _XOS_INCLUDE_INTERNAL_ before including xos.h"
-#endif
-
-#include
-#include "xos_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-// Use this macro to suppress compiler warnings for unused variables.
-
-#define UNUSED(x) (void)(x)
-
-
-#if XOS_DEBUG
-
-#include
-#include
-# define DPRINTF printf
-
-#else
-
-# define DPRINTF(x...) do {} while(0)
-
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Internal flags for thread creation.
-//-----------------------------------------------------------------------------
-#define XOS_THREAD_FAKE 0x8000 // Don't allocate stack (init and idle threads).
-
-
-//-----------------------------------------------------------------------------
-// Interrupt handler table entry. This structure defines one entry in the XOS
-// interrupt handler table.
-//-----------------------------------------------------------------------------
-typedef struct XosIntEntry {
- XosIntFunc * handler; // Pointer to handler function.
- void * arg; // Argument passed to handler function.
-#if XOS_OPT_INTERRUPT_SWPRI
- unsigned char level; // Interrupt level.
- unsigned char priority; // Interrupt priority.
- short reserved; // Reserved.
- unsigned int primask; // Mask of interrupts at higher priority.
-#else
- unsigned int ps; // Value of PS when running the handler.
-#endif
-} XosIntEntry;
-
-
-//-----------------------------------------------------------------------------
-// Extern variables.
-//-----------------------------------------------------------------------------
-extern unsigned xos_intlevel_mask;
-extern unsigned xos_intenable_mask;
-extern XosIntEntry xos_interrupt_table[XCHAL_NUM_INTERRUPTS];
-
-extern uint32_t xos_clock_freq;
-extern uint32_t xos_tick_period;
-extern uint64_t xos_system_ticks;
-extern uint64_t xos_system_cycles;
-extern uint32_t xos_num_ctx_switches;
-
-
-/*
-
-One thing I noticed is different between my initial idea of stack
-assignments to RTC threads, when comparing to interrupts, is that I
-expected each RTC thread priority to have its own stack, whereas
-interrupts of different priorities share an interrupt stack.
-
-It's not really a difference in memory usage, because when assigning
-multiple priorities to a stack, you have to add-up worst-case for
-all priorities. One possible functional difference is that with
-separate stacks per priority, it's possible to dynamically change
-the priority of an RTC thread (while it's running). Not sure how
-valuable that might be -- changing priority is useful with priority
-inheritance, to avoid priority inversion, but I don't know how often
-an RTC thread might acquire a lock (it couldn't block on acquiring a
-lock in the usual sense -- it could get queued waiting and be restarted
-when it becomes available, or use try_lock instead of lock).
-
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XOS_INTERNAL_H__ */
-
diff --git a/components/esp32/include/xtensa/xos_msgq.h b/components/esp32/include/xtensa/xos_msgq.h
deleted file mode 100644
index 30b9aa9032..0000000000
--- a/components/esp32/include/xtensa/xos_msgq.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/** @file */
-
-// xos_msgq.h - XOS Message Queue API and data structures.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// NOTE: Do not include this file directly in your application. Including
-// xos.h will automatically include this file.
-
-
-#ifndef __XOS_MSGQ_H__
-#define __XOS_MSGQ_H__
-
-#include "xos_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-//-----------------------------------------------------------------------------
-// XosMsgQueue is a multi-writer multi-reader message queue implementation.
-// It is completely thread-safe and can be used by interrupt handlers.
-// Interrupt handlers are guaranteed not to block when trying to send or
-// receive a message. Messages are copied into the queue. The queue contains
-// storage for a fixed number of messages defined at queue creation time.
-// Messages must be a multiple of 4 bytes long (padded if necessary) and the
-// message buffers must be 4-byte aligned.
-//-----------------------------------------------------------------------------
-
-
-//-----------------------------------------------------------------------------
-// Message Queue flags.
-//-----------------------------------------------------------------------------
-#define XOS_MSGQ_WAIT_PRIORITY 0x0000 ///< Wake waiters in priority order (default)
-#define XOS_MSGQ_WAIT_FIFO 0x0001 ///< Wake waiters in FIFO order
-#define XOS_MSGQ_FULL 0x0002 // Queue is full
-#define XOS_MSGQ_DELETED 0x8000 // Queue is deleted
-
-
-//-----------------------------------------------------------------------------
-///
-/// XosMsgQueue object.
-///
-//-----------------------------------------------------------------------------
-typedef struct XosMsgQueue {
- uint16_t flags; ///< queue flags
- uint16_t count; ///< # of messages queue can hold
- uint32_t msize; ///< message size in bytes
- uint16_t head; ///< write pointer
- uint16_t tail; ///< read pointer
- XosThreadQueue readq; ///< reader wait queue
- XosThreadQueue writeq; ///< writer wait queue
-#if XOS_MSGQ_DEBUG
- uint32_t sig; // debug signature
-#endif
-#if XOS_OPT_MSGQ_STATS
- uint32_t num_send; ///< # of messages put to queue
- uint32_t num_recv; ///< # of messages taken from queue
- uint32_t num_send_blks; ///< # of times thread blocked on send
- uint32_t num_recv_blks; ///< # of times thread blocked on recv
-#endif
- uint32_t msg[1]; ///< first word of message buffer
-} XosMsgQueue;
-
-
-//-----------------------------------------------------------------------------
-///
-/// Use these macros to statically or dynamically allocate a message queue.
-/// XOS_MSGQ_ALLOC allocates a static queue, while XOS_MSGQ_SIZE can be used
-/// to allocate memory via malloc() etc.
-///
-/// Static: this allocates a queue named "testq", containing 10 messages,
-/// each 16 bytes long.
-///
-/// XOS_MSGQ_ALLOC(testq, 10, 16);
-///
-/// Dynamic: this allocates a queue named "testq", containing 10 messages,
-/// each 16 bytes long.
-///
-/// XosMsgQueue * testq = malloc( XOS_MSGQ_SIZE(10, 16) );
-///
-/// \param name The queue name, i.e. the name of the pointer
-/// to the queue. Used as the queue handle in
-/// queue API calls.
-///
-/// \param num Number of messages to allocate in queue. Must be > 0.
-///
-/// \param size Message size in bytes. Must be > 0 and multiple of 4.
-///
-//-----------------------------------------------------------------------------
-
-#define XOS_MSGQ_ALLOC(name, num, size) \
- static uint8_t name ## _buf[ sizeof(XosMsgQueue) + ((num) * (size)) ]; \
- XosMsgQueue * name = (XosMsgQueue *) name ## _buf;
-
-#define XOS_MSGQ_SIZE(num, size) \
- (sizeof(XosMsgQueue) + ((num) * (size)))
-
-
-//-----------------------------------------------------------------------------
-///
-/// Create the message queue object. Memory for the queue must be allocated by
-/// the caller, either statically or via dynamic allocation. See the macros
-/// XOS_MSGQ_ALLOC and XOS_MSGQ_SIZE for examples.
-///
-/// \param msgq Handle (pointer) to message queue.
-///
-/// \param num Number of messages allocated in queue. Must be > 0.
-///
-/// \param size Message size in bytes. Must be > 0 and multiple of 4.
-///
-/// \param flags Queue flags:
-/// - XOS_MSGQ_WAIT_FIFO - blocked threads will be
-/// woken in FIFO order.
-/// - XOS_MSGQ_WAIT_PRIORITY - blocked threads will
-/// be woken in priority order (default).
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_msgq_create(XosMsgQueue * msgq, uint16_t num, uint32_t size, uint16_t flags);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Destroys the specified queue. Any waiting threads are unblocked with an
-/// error return. Any messages in the queue will be lost.
-///
-/// \param msgq Pointer to message queue.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_msgq_delete(XosMsgQueue * msgq);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Put a message into the queue. The message contents are copied into the next
-/// available message slot. If no space is available, this function will block
-/// if called from a thread, but will return immediately if called from an
-/// interrupt handler.
-///
-/// \param msgq Pointer to message queue.
-///
-/// \param msg Pointer to message buffer.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_msgq_put(XosMsgQueue * msgq, const uint32_t * msg);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Put a message into the queue. The message contents are copied into the next
-/// available message slot. If no space is available, this function will block
-/// if called from a thread, but will return immediately if called from an
-/// interrupt handler. The thread will be unblocked when space frees up in the
-/// queue or the timeout expires.
-///
-/// \param msgq Pointer to message queue.
-///
-/// \param msg Pointer to message buffer.
-///
-/// \param to_cycles Timeout in cycles. Convert from time to cycles
-/// using the helper functions provided in xos_timer.
-/// A value of zero indicates no timeout.
-///
-/// \return Returns XOS_OK on success, XOS_ERR_TIMEOUT on timeout, else error code.
-///
-/// NOTE: If XOS_OPT_WAIT_TIMEOUT is not enabled, then the timeout value is
-/// ignored, and no timeout will occur.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_msgq_put_timeout(XosMsgQueue * msgq, const uint32_t * msg, uint64_t to_cycles);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get a message from the queue. The message contents are copied into the
-/// buffer that must be provided. If no message is available, this function
-/// will block if called from a thread, but will return immediately if called
-/// from an interrupt handler.
-///
-/// \param msgq Pointer to message queue.
-///
-/// \param msg Pointer to message buffer.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_msgq_get(XosMsgQueue * msgq, uint32_t * msg);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get a message from the queue. The message contents are copied into the
-/// buffer that must be provided. If no message is available, this function
-/// will block if called from a thread, but will return immediately if called
-/// from an interrupt handler. The thread will be unblocked when a message
-/// arrives in the queue or the timeout expires.
-///
-/// \param msgq Pointer to message queue.
-///
-/// \param msg Pointer to message buffer.
-///
-/// \param to_cycles Timeout in cycles. Convert from time to cycles
-/// using the helper functions provided in xos_timer.
-/// A value of zero indicates no timeout.
-///
-/// \return Returns XOS_OK on success, XOS_ERR_TIMEOUT on timeout, else error code.
-///
-/// NOTE: If XOS_OPT_WAIT_TIMEOUT is not enabled, then the timeout value is
-/// ignored, and no timeout will occur.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_msgq_get_timeout(XosMsgQueue * msgq, uint32_t * msg, uint64_t to_cycles);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Check if the queue is empty.
-///
-/// \param msgq Pointer to message queue.
-///
-/// \return Returns nonzero if queue is empty, zero if queue is not empty.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_msgq_empty(XosMsgQueue * msgq);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Check if the queue is full.
-///
-/// \param msgq Pointer to message queue.
-///
-/// \return Returns nonzero if queue is full, zero if queue is not full.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_msgq_full(XosMsgQueue * msgq);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __XOS_MSGQ_H__
-
diff --git a/components/esp32/include/xtensa/xos_mutex.h b/components/esp32/include/xtensa/xos_mutex.h
deleted file mode 100644
index 9df5f9750b..0000000000
--- a/components/esp32/include/xtensa/xos_mutex.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/** @file */
-
-// xos_mutex.h - XOS Mutex API interface and data structures.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// NOTE: Do not include this file directly in your application. Including
-// xos.h will automatically include this file.
-
-#ifndef __XOS_MUTEX_H__
-#define __XOS_MUTEX_H__
-
-#include "xos_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Mutex flags.
-//-----------------------------------------------------------------------------
-#define XOS_MUTEX_WAIT_PRIORITY 0x0000 ///< Wake waiters in priority order (default)
-#define XOS_MUTEX_WAIT_FIFO 0x0001 ///< Wake waiters in FIFO order
-#define XOS_MUTEX_PRIORITY_CLG 0x0004 // Use priority ceiling
-#define XOS_MUTEX_PRIORITY_INV 0x0008 // Protect against priority inversion
-
-
-//-----------------------------------------------------------------------------
-///
-/// XosMutex object.
-///
-//-----------------------------------------------------------------------------
-typedef struct XosMutex {
- XosThread * owner; ///< Owning thread (null if unlocked).
- XosThreadQueue waitq; ///< Queue of waiters.
- uint32_t flags; ///< Properties.
- uint32_t priority;
- int32_t lock_count; ///< For recursive locking.
-#if XOS_MUTEX_DEBUG
- uint32_t sig; // Valid signature indicates inited.
-#endif
-} XosMutex;
-
-
-//-----------------------------------------------------------------------------
-///
-/// Initialize a mutex object before first use.
-///
-/// \param mutex Pointer to mutex object.
-///
-/// \param flags Creation flags:
-/// - XOS_MUTEX_WAIT_FIFO -- Queue waiting threads
-/// in fifo order.
-/// - XOS_MUTEX_WAIT_PRIORITY -- Queue waiting threads
-/// by priority. This is the default.
-/// - XOS_MUTEX_PRIORITY_CLG -- Use specified priority
-/// value as the mutex's priority ceiling. If the
-/// owning thread has a priority lower than the mutex's
-/// priority, then the thread will have its priority
-/// raised to the higher value as long as it owns the
-/// mutex.
-/// - XOS_MUTEX_PRIORITY_INV -- Protect against priority
-/// inversion. If there is a waiting thread with a
-/// higher priority than the current owner thread,
-/// then the owner thread's priority is raised to the
-/// higher value for as long as it owns the mutex.
-///
-/// \param priority Mutex's priority ceiling. This is used only if the
-/// XOS_MUTEX_PRIORITY_CLG flag is set.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-/// NOTE: XOS_MUTEX_PRIORITY_CLG and XOS_MUTEX_PRIORITY_INV are NOT supported
-/// in the current release. They will be supported in a future release.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_mutex_create(XosMutex * mutex, uint32_t flags, uint8_t priority);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Destroy a mutex object. Must have been previously initialized by calling
-/// xos_mutex_create().
-///
-/// \param mutex Pointer to mutex object.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_mutex_delete(XosMutex * mutex);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Take ownership of the mutex: block until the mutex is owned.
-/// The mutex must have been initialized.
-///
-/// \param mutex Pointer to mutex object.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_mutex_lock(XosMutex * mutex);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Take ownership of the mutex: block until the mutex is owned or the timeout
-/// expires. The mutex must have been initialized.
-///
-/// \param mutex Pointer to mutex object.
-///
-/// \param to_cycles Timeout in cycles. Convert from time to cycles
-/// using the helper functions provided in xos_timer.
-/// A value of zero indicates no timeout.
-///
-/// \return Returns XOS_OK on success, XOS_ERR_TIMEOUT on timeout, else error code.
-///
-/// NOTE: If XOS_OPT_WAIT_TIMEOUT is not enabled, then the timeout value is
-/// ignored, and no timeout will occur.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_mutex_lock_timeout(XosMutex * mutex, uint64_t to_cycles);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Release ownership of the mutex. The mutex must have been initialized and
-/// must be owned by the calling thread.
-///
-/// \param mutex Pointer to mutex object.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_mutex_unlock(XosMutex * mutex);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Try to take ownership of the mutex, but do not block if the mutex is taken.
-/// Return immediately. The mutex must have been initialized.
-///
-/// \param mutex Pointer to mutex object.
-///
-/// \return Returns XOS_OK on success (mutex owned), else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_mutex_trylock(XosMutex * mutex);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Return the state of the mutex (locked or unlocked) but do not attempt to
-/// take ownership. The mutex must have been initialized.
-///
-/// \param mutex Pointer to mutex object.
-///
-/// \return Returns 0 if the mutex is unlocked, 1 if it is locked, -1 on error.
-///
-//-----------------------------------------------------------------------------
-static inline int32_t
-xos_mutex_test(XosMutex * mutex)
-{
- XOS_ASSERT(mutex);
-
- if (mutex != XOS_NULL) {
- return (mutex->owner != XOS_NULL) ? 1 : 0;
- }
- return -1;
-}
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __XOS_MUTEX_H__
-
diff --git a/components/esp32/include/xtensa/xos_params.h b/components/esp32/include/xtensa/xos_params.h
deleted file mode 100644
index 3fca11f21a..0000000000
--- a/components/esp32/include/xtensa/xos_params.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/** @file */
-
-// xos_params.h - user-settable compile time parameters for XOS.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-#ifndef __XOS_PARAMS_H__
-#define __XOS_PARAMS_H__
-
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Number of thread priority levels. At this time XOS supports a maximum of
-/// 32 priority levels (0 - 31).
-///
-//-----------------------------------------------------------------------------
-#ifndef XOS_NUM_PRIORITY
-#define XOS_NUM_PRIORITY 16 // Default is 16
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Debug flags - Set to 1 to enable debug mode (and more verbose operation).
-/// Can be set individually, or define XOS_DEBUG_ALL to enable all of them.
-///
-/// - XOS_DEBUG -- Generic OS debug
-/// - XOS_COND_DEBUG -- Condition objects debug
-/// - XOS_EVENT_DEBUG -- Event objects debug
-/// - XOS_MSGQ_DEBUG -- Message queue debug
-/// - XOS_MUTEX_DEBUG -- Mutex objects debug
-/// - XOS_SEM_DEBUG -- Semaphore objects debug
-/// - XOS_THREAD_DEBUG -- Thread module debug
-/// - XOS_TIMER_DEBUG -- Timer module debug
-///
-/// WARNING: Enabling one or more of these flags will affect system performance
-/// and timing.
-///
-/// NOTE: Not all of these have been fully implemented.
-///
-//-----------------------------------------------------------------------------
-#if defined XOS_DEBUG_ALL
-
-#define XOS_DEBUG 1
-#define XOS_THREAD_DEBUG 1
-#define XOS_TIMER_DEBUG 1
-#define XOS_COND_DEBUG 1
-#define XOS_MUTEX_DEBUG 1
-#define XOS_SEM_DEBUG 1
-#define XOS_EVENT_DEBUG 1
-#define XOS_MSGQ_DEBUG 1
-
-#else
-
-#ifndef XOS_DEBUG
-#define XOS_DEBUG 0
-#endif
-#ifndef XOS_THREAD_DEBUG
-#define XOS_THREAD_DEBUG 0
-#endif
-#ifndef XOS_TIMER_DEBUG
-#define XOS_TIMER_DEBUG 0
-#endif
-#ifndef XOS_COND_DEBUG
-#define XOS_COND_DEBUG 0
-#endif
-#ifndef XOS_MUTEX_DEBUG
-#define XOS_MUTEX_DEBUG 0
-#endif
-#ifndef XOS_SEM_DEBUG
-#define XOS_SEM_DEBUG 0
-#endif
-#ifndef XOS_EVENT_DEBUG
-#define XOS_EVENT_DEBUG 0
-#endif
-#ifndef XOS_MSGQ_DEBUG
-#define XOS_MSGQ_DEBUG 0
-#endif
-
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set this option to 1 to enable runtime statistics collection for XOS.
-/// NOTE: Enabling this option does have some impact on runtime performance
-/// and OS footprint.
-///
-//-----------------------------------------------------------------------------
-#ifndef XOS_OPT_STATS
-#define XOS_OPT_STATS 1
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set this option to 1 to enable statistics tracking for message queues.
-/// enabling this will cause message queue objects to increase in size, and add
-/// some overhead to message queue processing.
-///
-//-----------------------------------------------------------------------------
-#ifndef XOS_OPT_MSGQ_STATS
-#define XOS_OPT_MSGQ_STATS 0
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Size of interrupt stack in bytes. Shared by all interrupt handlers. Must be
-/// sized to handle worst case nested interrupts. This is also used by the idle
-/// thread so must exist even if interrupts are not configured.
-///
-//-----------------------------------------------------------------------------
-#ifndef XOS_INT_STACK_SIZE
-#if XCHAL_HAVE_INTERRUPTS
-#define XOS_INT_STACK_SIZE 8192
-#else
-#define XOS_INT_STACK_SIZE 32
-#endif
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Default maximum interrupt level at which XOS primitives may be called.
-/// It is the level at which interrupts are disabled by default.
-/// See also description of xos_set_int_pri_level().
-///
-//-----------------------------------------------------------------------------
-#ifndef XOS_MAX_OS_INTLEVEL
-#define XOS_MAX_OS_INTLEVEL XCHAL_EXCM_LEVEL
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set this to 1 to enable stack checking. The stack is filled with a pattern
-/// on thread creation, and the stack is checked at certain times during system
-/// operation.
-/// WARNING: Enabling this option can have some impact on runtime performance.
-///
-//-----------------------------------------------------------------------------
-#ifndef XOS_OPT_STACK_CHECK
-#if XOS_DEBUG
-#define XOS_OPT_STACK_CHECK 1
-#else
-#define XOS_OPT_STACK_CHECK 0
-#endif
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set XOS_CLOCK_FREQ to the system clock frequency if this is known ahead of
-/// time. Otherwise, call xos_set_clock_freq() to set it at run time.
-///
-//-----------------------------------------------------------------------------
-#ifndef XOS_CLOCK_FREQ
-#define XOS_CLOCK_FREQ 1000000
-#endif
-#define XOS_DEFAULT_CLOCK_FREQ XOS_CLOCK_FREQ
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set this option to 1 to enable software prioritization of interrupts. The
-/// priority scheme applied is that a higher interrupt number at the same level
-/// will have higher priority.
-///
-//-----------------------------------------------------------------------------
-#ifndef XOS_OPT_INTERRUPT_SWPRI
-#define XOS_OPT_INTERRUPT_SWPRI 1
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set this option to 1 to use the thread-safe version of the C runtime library.
-/// You may need to enable this if you call C library functions from multiple
-/// threads -- see the documentation for the relevant C library to determine if
-/// this is necessary. This option increases the size of the TCB.
-/// NOTE: At this time only the newlib and xclib libraries are supported for
-/// thread safety.
-///
-//-----------------------------------------------------------------------------
-#include
-
-#ifndef XOS_OPT_THREAD_SAFE_CLIB
-
-#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
-#define XOS_OPT_THREAD_SAFE_CLIB 1
-#elif XSHAL_CLIB == XTHAL_CLIB_NEWLIB
-#define XOS_OPT_THREAD_SAFE_CLIB 1
-#else
-#define XOS_OPT_THREAD_SAFE_CLIB 0
-#endif
-
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set this option to 1 to enable the wait timeout feature. This allows waits
-/// on waitable objects to expire after a specified timeout.
-///
-//-----------------------------------------------------------------------------
-#ifndef XOS_OPT_WAIT_TIMEOUT
-#define XOS_OPT_WAIT_TIMEOUT 1
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set this option to 1 to enable threads waiting on timer objects. If this
-/// feature is not used, turning it off will make timer objects smaller, and
-/// reduce the time taken by timer expiry processing (by a small amount).
-///
-//-----------------------------------------------------------------------------
-#ifndef XOS_OPT_TIMER_WAIT
-#define XOS_OPT_TIMER_WAIT 1
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set this option to 1 to enable time-slicing between multiple threads at the
-/// same priority. If this option is enabled then on every timer tick the timer
-/// handler will switch out the current thread if there is another ready thread
-/// at the same priority, and allow the latter thread to run. Execution will be
-/// round robin switched among all the threads at the same priority.
-///
-/// Currently the time slice interval is fixed to be one timer tick.
-///
-/// This feature is most useful if fixed duration timer ticks are used.
-/// If dynamic ticking is enabled, then time slicing will work unpredictably
-/// because the interval between ticks will vary. In some cases it may be
-/// better to turn time slicing off.
-///
-//-----------------------------------------------------------------------------
-#ifndef XOS_OPT_TIME_SLICE
-#define XOS_OPT_TIME_SLICE 1
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __XOS_PARAMS_H__
-
diff --git a/components/esp32/include/xtensa/xos_regaccess.h b/components/esp32/include/xtensa/xos_regaccess.h
deleted file mode 100644
index 1fea5ddc28..0000000000
--- a/components/esp32/include/xtensa/xos_regaccess.h
+++ /dev/null
@@ -1,201 +0,0 @@
-
-// xos_regaccess.h - Access routines for various processor special registers.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-#ifndef __REGACCESS_H__
-#define __REGACCESS_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "xos_types.h"
-
-#include
-
-#if defined (__XCC__)
-#if XCHAL_HAVE_CCOUNT
-#include
-#endif
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Read CCOUNT register.
-//-----------------------------------------------------------------------------
-static __inline__ uint32_t xos_get_ccount(void)
-{
-#if XCHAL_HAVE_CCOUNT
-
-#if defined (__XCC__)
- return XT_RSR_CCOUNT();
-#else
- uint32_t ccount;
-
- __asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) );
- return ccount;
-#endif
-
-#else
-
- return 0;
-
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Read CCOMPARE0
-//-----------------------------------------------------------------------------
-static __inline__ uint32_t xos_get_ccompare0(void)
-{
-#if XCHAL_HAVE_CCOUNT
-
-#if defined (__XCC__)
- return XT_RSR_CCOMPARE0();
-#else
- uint32_t ccompare0;
-
- __asm__ __volatile__ ( "rsr %0, ccompare0" : "=a" (ccompare0));
- return ccompare0;
-#endif
-
-#else
-
- return 0;
-
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Read CCOMPARE1
-//-----------------------------------------------------------------------------
-#if (XCHAL_NUM_TIMERS > 1)
-static __inline__ uint32_t xos_get_ccompare1(void)
-{
-#if defined (__XCC__)
- return XT_RSR_CCOMPARE1();
-#else
- uint32_t ccompare1;
-
- __asm__ __volatile__ ( "rsr %0, ccompare1" : "=a" (ccompare1));
- return ccompare1;
-#endif
-}
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Read CCOMPARE2
-//-----------------------------------------------------------------------------
-#if (XCHAL_NUM_TIMERS > 2)
-static __inline__ uint32_t xos_get_ccompare2(void)
-{
-#if defined (__XCC__)
- return XT_RSR_CCOMPARE2();
-#else
- uint32_t ccompare2;
-
- __asm__ __volatile__ ( "rsr %0, ccompare2" : "=a" (ccompare2));
- return ccompare2;
-#endif
-}
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Write CCOMPARE0
-//-----------------------------------------------------------------------------
-static __inline__ void xos_set_ccompare0(uint32_t val)
-{
-#if XCHAL_HAVE_CCOUNT
-
-#if defined (__XCC__)
- XT_WSR_CCOMPARE0(val);
- XT_ISYNC();
-#else
- __asm__ __volatile__ (
- "wsr %0, ccompare0\n"
- "isync"
- :
- : "a" (val)
- );
-#endif
-
-#else
-
- // Empty
-
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Write CCOMPARE1
-//-----------------------------------------------------------------------------
-#if (XCHAL_NUM_TIMERS > 1)
-static __inline__ void xos_set_ccompare1(uint32_t val)
-{
-#if defined (__XCC__)
- XT_WSR_CCOMPARE1(val);
- XT_ISYNC();
-#else
- __asm__ __volatile__ (
- "wsr %0, ccompare1\n"
- "isync"
- :
- : "a" (val)
- );
-#endif
-}
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Write CCOMPARE2
-//-----------------------------------------------------------------------------
-#if (XCHAL_NUM_TIMERS > 2)
-static __inline__ void xos_set_ccompare2(uint32_t val)
-{
-#if defined (__XCC__)
- XT_WSR_CCOMPARE2(val);
- XT_ISYNC();
-#else
- __asm__ __volatile__ (
- "wsr %0, ccompare2\n"
- "isync"
- :
- : "a" (val)
- );
-#endif
-}
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __REGACCESS_H__
-
diff --git a/components/esp32/include/xtensa/xos_semaphore.h b/components/esp32/include/xtensa/xos_semaphore.h
deleted file mode 100644
index 42b7914ef0..0000000000
--- a/components/esp32/include/xtensa/xos_semaphore.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/** @file */
-
-// xos_semaphore.h - XOS Semaphore API interface and data structures.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// NOTE: Do not include this file directly in your application. Including
-// xos.h will automatically include this file.
-
-#ifndef __XOS_SEMAPHORE_H__
-#define __XOS_SEMAPHORE_H__
-
-#include "xos_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Semaphore flags.
-//-----------------------------------------------------------------------------
-#define XOS_SEM_WAIT_PRIORITY 0x0000 ///< Wake waiters in priority order (default)
-#define XOS_SEM_WAIT_FIFO 0x0001 ///< Wake waiters in FIFO order
-#define XOS_SEM_PRIORITY_INV 0x0004 // Protect against priority inversion
-
-
-//-----------------------------------------------------------------------------
-///
-/// XosSem object.
-///
-//-----------------------------------------------------------------------------
-typedef struct XosSem {
- uint32_t count; ///< Current count
- XosThreadQueue waitq; ///< Queue of waiters.
- uint32_t flags; ///< Properties.
-#if XOS_SEM_DEBUG
- uint32_t sig; // Valid signature indicates inited.
-#endif
-} XosSem;
-
-
-//-----------------------------------------------------------------------------
-///
-/// Initialize a semaphore object before first use.
-///
-/// \param sem Pointer to semaphore object.
-///
-/// \param flags Creation flags:
-/// - XOS_SEM_WAIT_FIFO -- queue waiting threads in
-/// fifo order.
-/// - XOS_SEM_WAIT_PRIORITY -- queue waiting threads
-/// by priority. This is the default.
-/// - XOS_SEM_PRIORITY_INV -- protect against priority
-/// inversion.
-///
-/// \param initial_count Initial count for semaphore on creation.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-/// NOTE: XOS_SEM_PRIORITY_INV is NOT supported in the current release. It will
-/// be supported in a future release.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_sem_create(XosSem * sem, uint32_t flags, uint32_t initial_count);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Destroy a semaphore object. Must have been previously created by calling
-/// xos_sem_create().
-///
-/// \param sem Pointer to semaphore object.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_sem_delete(XosSem * sem);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Decrement the semaphore count: block until the decrement is possible.
-/// The semaphore must have been initialized.
-///
-/// \param sem Pointer to semaphore object.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_sem_get(XosSem * sem);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Decrement the semaphore count: block until the decrement is possible or
-/// the timeout expires. The semaphore must have been initialized.
-///
-/// \param sem Pointer to semaphore object.
-///
-/// \param to_cycles Timeout in cycles. Convert from time to cycles
-/// using the helper functions provided in xos_timer.
-/// A value of zero indicates no timeout.
-///
-/// \return Returns XOS_OK on success, XOS_ERR_TIMEOUT on timeout, else error code.
-///
-/// NOTE: If XOS_OPT_WAIT_TIMEOUT is not enabled, then the timeout value is
-/// ignored, and no timeout will occur.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_sem_get_timeout(XosSem * sem, uint64_t to_cycles);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Increment the semaphore count. The semaphore must have been initialized.
-/// Remember that this action may wake up a waiting thread, and if that thread
-/// is higher priority then there will be an immediate context switch.
-///
-/// \param sem Pointer to semaphore object.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_sem_put(XosSem * sem);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Try to decrement the semaphore, but do not block if the semaphore count is
-/// zero. Return immediately. The semaphore must have been initialized.
-///
-/// \param sem Pointer to semaphore object.
-///
-/// \return Returns XOS_OK on success (semaphore decremented), else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_sem_tryget(XosSem * sem);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Return the count of the semaphore but do not attempt to decrement it.
-/// The semaphore must have been initialized.
-///
-/// \param sem Pointer to semaphore object.
-///
-/// \return Returns semaphore count, -1 on error.
-///
-//-----------------------------------------------------------------------------
-static inline int32_t
-xos_sem_test(XosSem * sem)
-{
- XOS_ASSERT(sem);
-
- return sem ? sem->count : -1;
-}
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __XOS_SEMAPHORE_H__
-
diff --git a/components/esp32/include/xtensa/xos_stopwatch.h b/components/esp32/include/xtensa/xos_stopwatch.h
deleted file mode 100644
index bf71cc388b..0000000000
--- a/components/esp32/include/xtensa/xos_stopwatch.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/** @file */
-
-// xos_stopwatch.h - XOS Stopwatch objects and related API.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// NOTE: Do not include this file directly in your application. Including
-// xos.h will automatically include this file.
-
-
-#ifndef __XOS_STOPWATCH_H__
-#define __XOS_STOPWATCH_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "xos_types.h"
-#include "xos_params.h"
-
-
-//-----------------------------------------------------------------------------
-// A stopwatch object can be used to track elapsed time and accumulate total
-// elapsed time over multiple execution periods. The stopwatch records the
-// time whenever its start function is called, and stops recording the time
-// when the stop function is called and updates its cumulative time counter.
-// The stopwatch keeps time in cycles. This can be converted to seconds etc.
-// by using the XOS conversion calls such as xos_cycles_to_secs().
-//-----------------------------------------------------------------------------
-
-
-//-----------------------------------------------------------------------------
-///
-/// XosStopwatch object.
-///
-//-----------------------------------------------------------------------------
-typedef struct XosStopwatch {
- uint64_t total; ///< Total accumulated cycle count
- uint64_t start; ///< Starting system cycle count
- uint16_t active; ///< Active flag (nonzero when active)
-} XosStopwatch;
-
-
-//-----------------------------------------------------------------------------
-///
-/// Initialize a stopwatch object.
-///
-/// \param sw Pointer to a stopwatch object.
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-static inline void
-xos_stopwatch_init(XosStopwatch * sw)
-{
- sw->total = 0;
- sw->start = 0;
- sw->active = 0;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Start a stopwatch. Starts cycle counting.
-/// Note that this does not necessarily start counting from zero. The current
-/// run (start-to-stop interval) will just get added to the accumulated count
-/// in the stopwatch if any.
-/// To reset the accumulated count, use xos_stopwatch_clear().
-///
-/// \param sw Pointer to a stopwatch object.
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-static inline void
-xos_stopwatch_start(XosStopwatch * sw)
-{
- XOS_ASSERT(!sw->active);
- sw->active = 1;
- sw->start = xos_get_system_cycles();
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Stop a stopwatch. Stops cycle counting and updates total.
-///
-/// \param sw Pointer to a stopwatch object.
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-static inline void
-xos_stopwatch_stop(XosStopwatch * sw)
-{
- XOS_ASSERT(sw->active);
- sw->active = 0;
- sw->total += xos_get_system_cycles() - sw->start;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get stopwatch accumulated count.
-///
-/// \param sw Pointer to a stopwatch object.
-///
-/// \return Returns the accumulated count.
-///
-//-----------------------------------------------------------------------------
-static inline uint64_t
-xos_stopwatch_count(XosStopwatch * sw)
-{
- return sw->total;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get elapsed time since stopwatch was started. If not started, returns zero.
-///
-/// \param sw Pointer to a stopwatch object.
-///
-/// \return Returns elapsed time in cycles.
-///
-//-----------------------------------------------------------------------------
-static inline uint64_t
-xos_stopwatch_elapsed(XosStopwatch * sw)
-{
- return sw->active ? xos_get_system_cycles() - sw->start : 0;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Clears a stopwatch. Resets the accumulated count to zero, and deactivates
-/// it if active.
-///
-/// \param sw Pointer to a stopwatch object.
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-static inline void
-xos_stopwatch_clear(XosStopwatch * sw)
-{
- xos_stopwatch_init(sw);
-}
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __XOS_STOPWATCH_H__
-
diff --git a/components/esp32/include/xtensa/xos_syslog.h b/components/esp32/include/xtensa/xos_syslog.h
deleted file mode 100644
index be56968fce..0000000000
--- a/components/esp32/include/xtensa/xos_syslog.h
+++ /dev/null
@@ -1,330 +0,0 @@
-/** @file */
-
-// xos_syslog.h - XOS Event logging module.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// NOTE: Do not include this file directly in your application. Including
-// xos.h will automatically include this file.
-
-
-#ifndef __XOS_SYSLOG_H__
-#define __XOS_SYSLOG_H__
-
-#include "xos_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-//-----------------------------------------------------------------------------
-// The XOS system log is an array of fixed size entries. The size of the log
-// is determined by the application, and memory for the log must be provided
-// at init time. Every time the log function is called, an entry is made in
-// the log and the next pointer advanced. When the log is full, it will wrap
-// around and start overwriting the oldest entries.
-// Logging can be done from C/C++ code as well as assembly code, and at any
-// interrupt level, even from high level interrupt handlers.
-//-----------------------------------------------------------------------------
-
-
-//-----------------------------------------------------------------------------
-// Defines.
-//-----------------------------------------------------------------------------
-#define XOS_SYSLOG_ENABLED 0x0001
-
-
-///----------------------------------------------------------------------------
-///
-/// Use this macro to compute how much memory to allocate for the syslog.
-///
-///----------------------------------------------------------------------------
-#define XOS_SYSLOG_SIZE(num_entries) \
- ( sizeof(XosSysLog) + ((num_entries - 1) * sizeof(XosSysLogEntry)) )
-
-
-///----------------------------------------------------------------------------
-///
-/// System log entry structure.
-///
-///----------------------------------------------------------------------------
-typedef struct XosSysLogEntry {
- uint32_t timestamp; ///< Timestamp in clock cycles
- uint32_t param1; ///< User defined value
- uint32_t param2; ///< User defined value
- struct XosSysLogEntry * next; ///< Link to next entry
-} XosSysLogEntry;
-
-
-///----------------------------------------------------------------------------
-///
-/// System log structure.
-///
-///----------------------------------------------------------------------------
-typedef struct XosSysLog {
- uint16_t flags; ///< Flags
- uint16_t size; ///< Number of entries
- XosSysLogEntry * next; ///< Next write position
- XosSysLogEntry entries[1]; ///< First entry
-} XosSysLog;
-
-
-//-----------------------------------------------------------------------------
-// Pointer to syslog area.
-//-----------------------------------------------------------------------------
-extern XosSysLog * xos_syslog;
-
-
-//----------------------------------------------------------------------------
-///
-/// Initialize the syslog. Initializing the log also enables it. The system
-/// log always wraps around when full and overwrites the oldest entries.
-///
-/// \param log_mem Pointer to allocated memory for the log.
-///
-/// \param num_entries The number of entries that the log can contain.
-///
-/// \return Returns nothing.
-///
-//----------------------------------------------------------------------------
-static inline void
-xos_syslog_init(void * log_mem, uint16_t num_entries)
-{
- uint16_t i;
-
- xos_syslog = (XosSysLog *) log_mem;
- xos_syslog->size = num_entries;
- xos_syslog->next = xos_syslog->entries;
-
- for (i = 0; i < num_entries - 1; i++) {
- xos_syslog->entries[i].next = &(xos_syslog->entries[i+1]);
- xos_syslog->entries[i].timestamp = 0;
- }
- xos_syslog->entries[i].next = xos_syslog->entries;
- xos_syslog->entries[i].timestamp = 0;
-
- xos_syslog->flags = XOS_SYSLOG_ENABLED;
-}
-
-
-///----------------------------------------------------------------------------
-///
-/// Reset the syslog. All entries made up to now are abandoned and the write
-/// pointer is set to the first entry location.
-///
-/// No parameters.
-///
-/// \return Returns nothing.
-///
-///----------------------------------------------------------------------------
-static inline void
-xos_syslog_clear()
-{
-#if XCHAL_HAVE_INTERRUPTS
- uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
-#endif
-
- xos_syslog_init(xos_syslog, xos_syslog->size);
-#if XCHAL_HAVE_INTERRUPTS
- xos_restore_int_pri_level(ps);
-#endif
-}
-
-
-///----------------------------------------------------------------------------
-///
-/// Enable logging to the syslog. This function needs to be called only if
-/// logging had been previously disabled via xos_syslog_disable(), since
-/// initializing the syslog automatically enables it.
-///
-/// No parameters.
-///
-/// \return Returns nothing.
-///
-///----------------------------------------------------------------------------
-static inline void
-xos_syslog_enable()
-{
-#if XCHAL_HAVE_INTERRUPTS
- uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
-#endif
-
- xos_syslog->flags |= XOS_SYSLOG_ENABLED;
-#if XCHAL_HAVE_INTERRUPTS
- xos_restore_int_pri_level(ps);
-#endif
-}
-
-
-///----------------------------------------------------------------------------
-///
-/// Disable logging to the syslog. It is sometimes useful to disable logging
-/// while the log is being examined or dumped.
-///
-/// No parameters.
-///
-/// \return Returns nothing.
-///
-///----------------------------------------------------------------------------
-static inline void
-xos_syslog_disable()
-{
-#if XCHAL_HAVE_INTERRUPTS
- uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
-#endif
- xos_syslog->flags &= ~XOS_SYSLOG_ENABLED;
-#if XCHAL_HAVE_INTERRUPTS
- xos_restore_int_pri_level(ps);
-#endif
-}
-
-
-///----------------------------------------------------------------------------
-///
-/// Write an entry into the syslog. This function does disable all interrupts
-/// since logging can be done from interrupt handlers as well. It will write
-/// into the log only if the log exists and is enabled.
-///
-/// \param param1 User defined value.
-///
-/// \param param2 User defined value.
-///
-/// \return Returns nothing.
-///
-///----------------------------------------------------------------------------
-static inline void
-xos_syslog_write(uint32_t param1, uint32_t param2)
-{
- if (xos_syslog != XOS_NULL) {
-#if XCHAL_HAVE_INTERRUPTS
- uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
-#endif
-
- if ((xos_syslog->flags & XOS_SYSLOG_ENABLED) != 0) {
- XosSysLogEntry * next = xos_syslog->next;
-
- next->timestamp = xos_get_ccount();
- next->param1 = param1;
- next->param2 = param2;
-
- xos_syslog->next = next->next;
- }
-
-#if XCHAL_HAVE_INTERRUPTS
- xos_restore_int_pri_level(ps);
-#endif
- }
-}
-
-
-///----------------------------------------------------------------------------
-///
-/// Read the first (oldest) entry in the syslog. Will return an error if the
-/// log has not been created or is empty. Storage to copy the entry must be
-/// provided by the caller.
-///
-/// \param entry Pointer to storage where the entry data will be
-/// copied. This pointer must be passed to
-/// xos_syslog_get_next().
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-///----------------------------------------------------------------------------
-static inline int32_t
-xos_syslog_get_first(XosSysLogEntry * entry)
-{
- if (xos_syslog == XOS_NULL) {
- return XOS_ERR_NOT_FOUND;
- }
-
- if (entry != XOS_NULL) {
-#if XCHAL_HAVE_INTERRUPTS
- uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
-#endif
- XosSysLogEntry * next = xos_syslog->next;
-
- // 'next' should be pointing to the next entry to be overwritten, if we
- // have wrapped. This means it is the oldest entry. However if this entry
- // has a zero timestamp then we have not wrapped, in which case we must
- // look at the first entry in the list.
- if (next->timestamp == 0) {
- next = xos_syslog->entries;
- }
-
- *entry = *next;
-#if XCHAL_HAVE_INTERRUPTS
- xos_restore_int_pri_level(ps);
-#endif
- return entry->timestamp ? XOS_OK : XOS_ERR_NOT_FOUND;
- }
-
- return XOS_ERR_INVALID_PARAMETER;
-}
-
-
-///----------------------------------------------------------------------------
-///
-/// Get the next sequential entry from the syslog. This function must be called
-/// only after xos_syslog_get_first() has been called.
-///
-/// \param entry Pointer to storage where entry data will be copied.
-/// Must be the same pointer that was passed in the call
-/// to xos_syslog_get_first(), as it is used to keep track
-/// of the current position.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-///----------------------------------------------------------------------------
-static inline int32_t
-xos_syslog_get_next(XosSysLogEntry * entry)
-{
- if (entry != XOS_NULL) {
-#if XCHAL_HAVE_INTERRUPTS
- uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
-#endif
- XosSysLogEntry * next = entry->next;
- int32_t ret = XOS_OK;
-
- // Make sure we're not pointing past the last entry.
- if ((next != XOS_NULL) && (next != xos_syslog->next) && (next->timestamp != 0)) {
- *entry = *next;
- }
- else {
- ret = XOS_ERR_NOT_FOUND;
- }
-#if XCHAL_HAVE_INTERRUPTS
- xos_restore_int_pri_level(ps);
-#endif
- return ret;
- }
-
- return XOS_ERR_INVALID_PARAMETER;
-}
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __XOS_SYSLOG_H__
-
diff --git a/components/esp32/include/xtensa/xos_thread.h b/components/esp32/include/xtensa/xos_thread.h
deleted file mode 100644
index 8bc5077eca..0000000000
--- a/components/esp32/include/xtensa/xos_thread.h
+++ /dev/null
@@ -1,1086 +0,0 @@
-/** @file */
-
-// xos_thread.h - XOS Thread API interface and data structures.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// NOTE: Do not include this file directly in your application. Including
-// xos.h will automatically include this file.
-
-
-#ifndef __XOS_THREAD_H__
-#define __XOS_THREAD_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "xos_types.h"
-#include "xos_params.h"
-
-
-//-----------------------------------------------------------------------------
-// Number of thread priority levels.
-//-----------------------------------------------------------------------------
-#ifndef XOS_NUM_PRIORITY
-#error "XOS_NUM_PRIORITY must be defined (in xos_params.h)."
-#endif
-#if XOS_NUM_PRIORITY > 32
-#error "The number of thread priority levels (XOS_NUM_PRIORITY) must be <= 32."
-#endif
-#define XOS_MAX_PRIORITY (XOS_NUM_PRIORITY)
-
-
-//-----------------------------------------------------------------------------
-// Macro for thread self pointer.
-//-----------------------------------------------------------------------------
-#define XOS_THREAD_SELF (xos_thread_id())
-
-
-//-----------------------------------------------------------------------------
-///
-/// Thread entry function pointer type.
-///
-//-----------------------------------------------------------------------------
-typedef int32_t (XosThreadFunc)(void * arg, int32_t wake_value);
-
-
-//-----------------------------------------------------------------------------
-// Thread switcher function signature.
-//-----------------------------------------------------------------------------
-typedef struct XosThread XosThread;
-typedef int32_t (XosSwitchFunc)(XosThread *);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Condition evaluation callback function pointer type.
-///
-//-----------------------------------------------------------------------------
-typedef int32_t (XosCondFunc)(void * arg, int32_t sig_value, XosThread * thread);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Thread exit handler function pointer type.
-///
-//-----------------------------------------------------------------------------
-typedef int32_t (XosThdExitFunc)(int32_t exitcode);
-
-
-//-----------------------------------------------------------------------------
-// Thread queue structure. Used to implement the ready queues as well
-// as the wait queues.
-//-----------------------------------------------------------------------------
-typedef struct XosThreadQueue {
- XosThread * head; // Pointer to first thread in queue, or 0 if none.
- XosThread ** tail; // Pointer to last thread's r_next pointer, or
- // to "head" if none.
-} XosThreadQueue;
-
-
-//-----------------------------------------------------------------------------
-// Stack frame for a thread that is not running. That is, it has either
-// been preempted or has yielded.
-//-----------------------------------------------------------------------------
-typedef union XosFrame {
- XosExcFrame e; // resume_fn == &xos_resume_preempted_thread
- XosCoopFrame c; // resume_fn == &xos_resume_cooperative_thread
- // nothing for resume_fn == &xos_resume_idle_thread
- // nothing for resume_fn == &xos_resume_by_restart
-} XosFrame;
-
-
-//-----------------------------------------------------------------------------
-// Thread Control Block. Tracks the state and control information associated
-// with a thread.
-//
-// IMPORTANT: keep this in sync with TCB_*** offsets in xos_common.h .
-//-----------------------------------------------------------------------------
-struct XosThread {
- XosThread * r_next; // 00 Next thread in queue (eg. ready queue of
- // its priority, or some queue of blocked threads)
- // Should be NULL if not in any queue.
-
- XosThread ** r_pprev; // 04 Points to previous queue entry's r_next
- // pointer (i.e. to itself), or to queue head
- // if first in queue. NULL if not in any queue.
-
- XosThread * all_next; // 08 Next in list of all threads.
-
- void * resume_fn; // 12 Pointer to the routine to be called to
- // resume this thread. On entry to such code:
- // a2 == xos_curr_threadptr (thread being resumed)
- // a3 == &xos_globals
-
- XosFrame * esf; // 16 Pointer to saved exception stack frame,
- // just below thread's current stack pointer.
- // For RTC threads, this is valid only while the
- // thread is preempted, not when it is blocked.
-
- void * tie_save; // 20 TIE state save area. May be NULL if there
- // is not TIE state saved for this thread.
-
- int32_t wake_value; // 24 Value returned from block call (by wake call)
- // (for RTC: pass this to start function??)
-
- XosSwitchFunc * switch_fn; // 28 Pointer to a function that
- // can be called from within this thread, to save
- // this thread's state and switch to a specified
- // other thread. Returns wake value.
-
- void * stack_base; // 32 Base of stack as specified by thread creator.
-
- void * stack_end; // 36 End of stack (adjusted for TIE state save area
- // if any).
-
- XosThreadFunc * entry; // 40 Pointer to thread entry function. Used for
- // RTC thread restart.
-
- void * arg; // 44 Argument value passed to entry function.
-
- bool ready; // 48 Set when thread is ready to run, and is in
- // its priority queue (i.e. r_pprev is set when
- // this flag is set).
-
- bool in_exit; // Exit flag, nonzero when in exit processing.
-
- int8_t priority; // Thread priority, 0 .. (XOS_MAX_PRI - 1). Higher
- // numbers have higher priority. This must only be
- // changed when thread is not ready, or by calling
- // xos_thread_set_priority().
-
- int8_t preempt_pri; // This thread's preemption blocking priority.
- // (preempt_pri >= priority). A thread's priority
- // must be higher than another's preempt_pri to be
- // able to preempt it. Note that preempt_pri can
- // change during runtime e.g. due to priority
- // inheritance.
-
- uint32_t flags; // 52 Thread creation flags.
-
- const char * name; // 56 Thread name (mainly for debug).
-
- const char * block_cause; // 60 Reason for blocking. Valid only when thread
- // not ready (r_pprev == 0).
-
- XosThread * container; // 64 Thread whose stack will be used to run
- // this thread. Valid for RTC threads only, else NULL.
-
- XosThdExitFunc * exit_func; // 68 Thread exit handler function pointer.
-
- XosThreadQueue exit_waiters; // 72 Queue of threads waiting for this one to exit.
-
- XosThreadQueue * wq_ptr; // 80 If this thread is in a wait queue, this
- // points to the queue. Must be NULL when
- // thread not in a queue.
-
- XosCondFunc * cond_fn; // 84 Condition function. Valid only while thread
- // is blocked on condition.
-
- void * cond_arg; // 88 Argument to be passed to condition function.
-
- uint16_t cp_mask; // 92 Mask of coprocessors used.
- uint16_t cp_saved; // 94 Mask of coprocessors saved.
-
- uint32_t event_bits; // 96 event bits
- uint32_t event_mask; // 100 event bit mask
- uint32_t event_flags; // 104 event flags
-
- void * clib_ptr; // 108 Pointer to C lib context struct.
-
- uint32_t sig; // 112 Signature of valid TCB
-
- uint32_t resume_ccount; // 116 cycle count at resume
- uint64_t cycle_count; // 120 number of cycles consumed (approx).
- // NOTE: must be 8-byte aligned
- uint32_t normal_resumes; // 128 Number of non-preemptive resumptions.
- uint32_t preempt_resumes;// 132 Number of preemptive resumptions.
-
-#if XOS_OPT_THREAD_SAFE_CLIB
- CLIB_THREAD_STRUCT; // C library context area.
-#endif
-};
-
-
-//-----------------------------------------------------------------------------
-// User-visible flags for xos_thread_create().
-//-----------------------------------------------------------------------------
-#define XOS_THREAD_SUSPEND 0x0001 ///< Create suspended instead of ready
-#define XOS_THREAD_RTC 0x0002 ///< Run-to-completion thread
-#define XOS_THREAD_NO_CP 0x0004 ///< Thread does not use coprocessors
-
-
-//-----------------------------------------------------------------------------
-// Flags used by thread creation extra parameters.
-//-----------------------------------------------------------------------------
-#define XOS_TP_COPROC_MASK 0x0001
-#define XOS_TP_PREEMPT_PRI 0x0002
-#define XOS_TP_EXIT_HANDLER 0x0004
-
-
-//-----------------------------------------------------------------------------
-// Thread creation extra parameters.
-//-----------------------------------------------------------------------------
-typedef struct XosThreadParm {
- uint32_t parms_mask; // Combination of XOS_TP_xxx flags indicating
- // which parameters are valid.
-
- uint16_t cp_mask; // Mask of coprocessors the thread can access.
-
- uint32_t preempt_pri; // Initial preemption blocking priority. Can be
- // changed later via xos_thread_set_priority().
-
- XosThdExitFunc * handler; // Exit handler function.
-
-} XosThreadParm;
-
-
-//-----------------------------------------------------------------------------
-// Wrapper struct for RTC (run to completion) thread.
-//-----------------------------------------------------------------------------
-typedef struct XosRtcThread {
- struct XosThread thread;
-} XosRtcThread;
-
-
-//-----------------------------------------------------------------------------
-// External variables.
-//-----------------------------------------------------------------------------
-extern XosThread * xos_curr_threadptr; // Current active thread
-extern XosThread * xos_next_threadptr; // Next ready thread
-extern XosThread * xos_all_threads; // List of all threads
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set thread creation parameter: the group of coprocessors that this thread
-/// will use. This must be set during thread creation, and cannot be changed
-/// after the thread has been created. Defining this allows reduction of
-/// memory usage (for CP state saving) in some circumstances, and can also
-/// speed up the context switch time.
-///
-/// NOTE: Support for this is not currently implemented. If a thread uses
-/// any coprocessor, space for all coprocessors must be reserved.
-///
-/// \param parms Thread creation parameter structure. Must be
-/// allocated by the caller.
-///
-/// \param cp_mask Bitmask of coprocessors thread is allowed to
-/// use. Bit 0 for coprocessor 0, etc.
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-static inline void
-xos_threadp_set_cp_mask(XosThreadParm * parms, uint16_t cp_mask)
-{
- if (parms != XOS_NULL) {
- parms->parms_mask |= XOS_TP_COPROC_MASK;
- parms->cp_mask = cp_mask;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set thread creation parameter: thread pre-emption priority.
-///
-/// \param parms Thread creation parameter structure. Must be
-/// allocated by caller.
-///
-/// \param preempt_pri Thread pre-emption blocking priority.
-/// From 0 .. XOS_NUM_PRIORITY - 1.
-/// Must be greater or equal to the thread priority
-/// (if not, is automatically set to thread priority).
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-static inline void
-xos_threadp_set_preemption_priority(XosThreadParm * parms, int8_t preempt_pri)
-{
- if (parms != XOS_NULL) {
- parms->parms_mask |= XOS_TP_PREEMPT_PRI;
- parms->preempt_pri = preempt_pri;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set thread creation parameter: thread exit handler.
-///
-/// \param parms Thread creation parameter structure. Must be
-/// allocated by caller.
-///
-/// \param handler Exit handler function.
-///
-/// \return Returns nothing.
-//-----------------------------------------------------------------------------
-static inline void
-xos_threadp_set_exit_handler(XosThreadParm * parms, XosThdExitFunc * handler)
-{
- if (parms != XOS_NULL) {
- parms->parms_mask |= XOS_TP_EXIT_HANDLER;
- parms->handler = handler;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Create a new thread. If the thread is not created suspended, then it will
-/// be made ready as soon as it is created, and will immediately run if it is
-/// the highest priority non-blocked thread in the system.
-///
-/// \param thread Pointer to the thread descriptor (an otherwise
-/// unused XosThread structure, usually allocated
-/// by the caller for the lifetime of the thread,
-/// for example as a global variable).
-///
-/// \param container Pointer to separate thread acting as "container"
-/// for this one. At the moment, this is only meaningful
-/// for run-to-completion (RTC) threads (identified with
-/// the XOS_THREAD_RTC flag), in which case the container
-/// must have the same priority and also be an RTC thread.
-/// (The priority restriction may be lifted in a future
-/// implementation, with appropriate constraints on dynamic
-/// reprioritization of the created thread).
-///
-/// \param entry Thread entry function, takes one argument.
-///
-/// \param arg Argument "void*" that is passed to the thread function.
-///
-/// \param name Unique name of the thread, for debug/display purposes.
-/// This string must be valid for the lifetime of the thread
-/// (only a pointer to it is stored in the thread control block).
-/// Typically consists of identifier chars with no spaces.
-///
-/// \param stack Base of initial stack for the thread, allocated by the
-/// caller. Need not be aligned (initial stack pointer will be
-/// computed and aligned from given stack base and size).
-/// Required argument, except for run-to-completion threads
-/// when container is non-NULL, in which case the container's
-/// stack is used and this argument must be NULL.
-///
-/// \param stack_size Size of the stack, in bytes.
-/// NOTE: stack should be at least XOS_STACK_EXTRA bytes plus
-/// whatever the thread actually needs if the thread will use
-/// coprocessors/TIE state. If the thread will not touch the
-/// coprocessors, then it should be XOS_STACK_EXTRA_NO_CP
-/// plus whatever the thread actually needs.
-/// Recommended minimum stack sizes are defined by the constants
-/// XOS_STACK_MIN_SIZE and XOS_STACK_MIN_SIZE_NO_CP.
-///
-/// For run-to-completion threads where container is non-NULL,
-/// stack_size specifies the minimum stack size required for
-/// the thread; it should be smaller or equal to the container's
-/// stack.
-///
-/// \param priority Initial thread priority. From 0 .. XOS_MAX_PRI - 1.
-/// Higher numbers are higher priority.
-///
-/// \param parms Pointer to extra parameters structure, or 0 if none given.
-/// Use xos_thread_p_***() functions to set parameters in the
-/// structure.
-///
-/// \param flags Option flags:
-/// - XOS_THREAD_SUSPEND -- Leave thread suspended instead of
-/// making it ready. The thread can be made ready to run later
-/// by calling xos_thread_resume().
-/// - XOS_THREAD_RTC -- Run-to-completion thread.
-/// - XOS_THREAD_NO_CP -- Thread does not use coprocessors.
-/// No coprocessor state will be saved for this thread.
-/// Threads that have this flag set will not allocate any
-/// storage for saving coprocessor state and so can have
-/// smaller stacks.
-///
-/// NOTE: xos_start_main() calls xos_thread_create() to convert main() into the 'main'
-/// thread.
-///
-/// \return Returns XOS_OK if successful, error code otherwise.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_thread_create(XosThread * thread,
- XosThread * container,
- XosThreadFunc * entry,
- void * arg,
- const char * name,
- void * stack,
- uint32_t stack_size,
- int32_t priority,
- XosThreadParm * parms,
- uint32_t flags );
-
-
-//-----------------------------------------------------------------------------
-///
-/// Remove thread and free up all resources. Thread must have exited already.
-/// After this call returns, all resources allocated to the thread (e.g. TCB,
-/// stack space, etc.) can be reused.
-///
-/// \param thread Handle of thread to be deleted.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-/// NOTE: A thread cannot call this on itself.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_thread_delete(XosThread * thread);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Force the thread to terminate. The thread execution is aborted, but exit
-/// processing will still happen, i.e. the exit handler (if any) will be run.
-/// After termination, any other threads waiting on this thread are notified.
-/// This function cannot be called on the current thread.
-///
-/// \param thread Handle of thread to be aborted.
-///
-/// \param exitcode Exit code returned to any waiting threads.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-/// NOTE: If the thread is blocked waiting for something, the wait is aborted
-/// and the thread is made ready.
-/// NOTE: The thread is not guaranteed to have exited when this call returns.
-/// It will be made ready and set up for exit processing, but when the exit
-/// processing will actually happen depends on the state of the system and
-/// the priority of the thread being aborted.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_thread_abort(XosThread * thread, int32_t exitcode);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Exit the current thread. The exit handler (if any) will be run before the
-/// thread terminates.
-///
-/// \param exitcode Exit code to be returned to any waiting threads.
-///
-/// \return This function does not return.
-///
-/// NOTE: This is automatically called if the thread returns from its entry
-/// function. The entry function's return value will be passed as the exit
-/// code.
-///
-//-----------------------------------------------------------------------------
-void
-xos_thread_exit(int32_t exitcode);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Wait until the specified thread exits and get its exit code. If the thread
-/// has exited already, an error will be returned.
-///
-/// \param thread The thread to wait for. Cannot be "self", i.e.
-/// one cannot wait on one's own exit.
-///
-/// \param p_exitcode If not null, the exit code will be returned here.
-///
-/// \return Returns XOS_OK on sucess, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_thread_join(XosThread * thread, int32_t * p_exitcode);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Yield the CPU to the next thread in line. The calling thread remains ready
-/// and is placed at the tail of the ready queue at its current priority level.
-/// If there are no threads at the same priority level that are ready to run,
-/// then this call will return immediately.
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-void
-xos_thread_yield();
-
-
-//-----------------------------------------------------------------------------
-///
-/// Suspend the specified thread. The thread will remain suspended until
-/// xos_thread_resume() has been called on it. If the thread is already blocked
-/// on some other condition, then this function will return an error.
-///
-/// \param thread Handle of thread being suspended. A thread can
-/// use the special handle XOS_THREAD_SELF to suspend
-/// itself.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_thread_suspend(XosThread * thread);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Resume a suspended thread. If the thread is not suspended or is blocked on
-/// some other condition then this function will do nothing. Otherwise, it will
-/// be made ready, and this can cause an immediate context switch if the thread
-/// is at a higher priority than the calling thread.
-///
-/// \param thread Handle of thread being resumed.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_thread_resume(XosThread * thread);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get the priority of the specified thread. This returns the priority of the
-/// queried thread at this instant, however this can change at any time due to
-/// other activity in the system.
-///
-/// \param thread Handle of thread being queried. A thread can use
-/// the special handle XOS_THREAD_SELF to query itself.
-///
-/// \return Returns the thread's current priority, or -1 if the thread handle
-/// is not valid.
-///
-//-----------------------------------------------------------------------------
-static inline int32_t
-xos_thread_get_priority(XosThread * thread)
-{
- XOS_ASSERT(thread);
- return thread ? thread->priority : -1;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set the priority of the specified thread. The thread must exist.
-///
-/// \param thread Handle of thread being affected. A thread can
-/// use the special handle XOS_THREAD_SELF to specify
-/// itself.
-///
-/// \param priority The new priority level to be set.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-/// NOTE: Calling this function can result in a scheduler activation, and the
-/// caller may be suspended as a result.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_thread_set_priority(XosThread * thread, int32_t priority);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Return the name of the specified thread.
-///
-/// \param thread Handle of thread being queried. A thread can use
-/// the special handle XOS_THREAD_SELF to specify
-/// itself.
-///
-/// \return Returns a pointer to the name string if available, else NULL.
-///
-//-----------------------------------------------------------------------------
-static inline const char *
-xos_thread_get_name(XosThread * thread)
-{
- XOS_ASSERT(thread);
- return thread ? thread->name : 0;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set the name of the specified thread.
-///
-/// \param thread Handle of thread whose name is to be set. A thread
-/// can use the special handle XOS_THREAD_SELF to specify
-/// itself.
-///
-/// \param name Pointer to the new name string. The string is not
-/// copied, only the pointer is saved. So the string
-/// must be persistent for the life of the thread.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-static inline int32_t
-xos_thread_set_name(XosThread * thread, const char * name)
-{
- XOS_ASSERT(thread);
- if (thread != XOS_NULL) {
- thread->name = name;
- return XOS_OK;
- }
-
- return XOS_ERR_INVALID_PARAMETER;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set an exit handler for the specified thread. The exit handler is run when
-/// the thread terminates, either by calling xos_thread_exit() or by returning
-/// from its entry function. It will also be called if the thread is being
-/// terminated due to e.g. an unhandled exception.
-///
-/// The handler must be a function defined as e.g.:
-///
-/// int32_t exit_handler(int32_t exitcode);
-///
-/// The exit handler runs in the context of the exiting thread, and can call
-/// system services. It is provided with a single parameter which is the
-/// thread's exit code (the exit code may be set to an error code if the
-/// thread is being terminated due to an error or exception). The handler
-/// must return a value which will be set as the thread's exit code.
-///
-/// \param thread Handle of the thread for which the handler is
-/// to be installed. A thread can use the special
-/// handle XOS_THREAD_SELF to specify itself.
-///
-/// \param func Pointer to exit handler function. To clear an
-/// existing handler, pass NULL as the pointer.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_thread_set_exit_handler(XosThread * thread, XosThdExitFunc * func);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Return the ID (handle) of the current thread.
-///
-/// \return Returns the handle of the current thread. This handle can be
-/// used in all XOS system calls.
-///
-/// NOTE: If called from interrupt context, returns the handle of the thread
-/// that was preempted.
-///
-//-----------------------------------------------------------------------------
-static inline XosThread *
-xos_thread_id()
-{
- return xos_curr_threadptr;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Return the coprocessor mask for the specified thread.
-///
-/// \param thread Handle of thread being queried.
-///
-/// \return Returns the mask for the specified thread if available, else 0.
-///
-//-----------------------------------------------------------------------------
-static inline uint16_t
-xos_thread_cp_mask(XosThread * thread)
-{
- XOS_ASSERT(thread);
- return thread ? thread->cp_mask : 0;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Return the wake value for the specified thread.
-///
-/// \return thread Handle of thread being queried.
-///
-/// \return Returns The last set wake value. There is no way to detect what
-/// action set the wake value and when.
-///
-//-----------------------------------------------------------------------------
-static inline int32_t
-xos_thread_get_wake_value(XosThread * thread)
-{
- XOS_ASSERT(thread);
- return thread ? thread->wake_value : 0;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Return the current value of the event bits for the current thread.
-/// This function takes no parameters.
-///
-/// \return Returns the current value of the event bits. The event bits
-/// are set when the thread is woken from an event wait. They will
-/// not change while the thread is running. There is no way to
-/// determine when the event bits were last updated.
-///
-//-----------------------------------------------------------------------------
-static inline uint32_t
-xos_thread_get_event_bits(void)
-{
- XosThread * thread = xos_thread_id();
- return thread ? thread->event_bits : 0;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Enum values for thread state.
-///
-//-----------------------------------------------------------------------------
-typedef enum xos_thread_state_t {
- XOS_THREAD_STATE_INVALID = 0, ///< Invalid thread
- XOS_THREAD_STATE_BLOCKED, ///< Thread is blocked
- XOS_THREAD_STATE_READY, ///< Thread is ready to run
- XOS_THREAD_STATE_RUNNING, ///< Thread is running
- XOS_THREAD_STATE_EXITED, ///< Thread has exited
-} xos_thread_state_t;
-
-
-//-----------------------------------------------------------------------------
-///
-/// Return the state of the specified thread.
-///
-/// \param thread Handle of thread being queried.
-///
-/// \return Returns one of the following values:
-/// - XOS_THREAD_STATE_RUNNING -- The thread is currently running.
-/// - XOS_THREAD_STATE_READY -- The thread is ready to run.
-/// - XOS_THREAD_STATE_BLOCKED -- The thread is blocked on something.
-/// - XOS_THREAD_STATE_INVALID -- The thread handle is invalid.
-/// - XOS_THREAD_STATE_EXITED -- The thread has exited.
-///
-//-----------------------------------------------------------------------------
-xos_thread_state_t
-xos_thread_get_state(XosThread * thread);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Disable thread preemption. Prevents context switching to another thread.
-/// However, interrupt handlers will still continue to be run. Multiple calls
-/// will nest, and the same number of calls to xos_preemption_enable() will be
-/// required to re-enable preemption. If the calling thread yields the CPU or
-/// exits without enabling preemption, it will cause a system halt.
-/// If the calling thread encounters a fatal error, preemption will be enabled
-/// during fatal error handling.
-///
-/// \return Returns the new value of preemption disable flag after this call.
-///
-/// NOTE: Cannot be called from interrupt context.
-///
-//-----------------------------------------------------------------------------
-uint32_t
-xos_preemption_disable(void);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Enable thread preemption. Has no effect if preemption was already enabled.
-/// Otherwise, it decrements the value of the preemption disable flag and if
-/// the value goes to zero, enables preemption.
-///
-/// \return Returns the new value of preemption disable flag after this call.
-///
-/// NOTE: If scheduling gets enabled, it may cause an immediate context switch
-/// if higher priority threads are ready.
-///
-//-----------------------------------------------------------------------------
-uint32_t
-xos_preemption_enable(void);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Initialize XOS thread support and start scheduler.
-///
-/// Must be called from main() before calling any other thread function.
-/// This function initializes thread support, creates the idle thread, and
-/// starts the scheduler. It does not return to its caller. This means that
-/// at least one user thread must be created before calling xos_start().
-/// Otherwise, the scheduler will run the idle thread since it will be the
-/// only thread in the system, and no other thread can be created.
-///
-/// NOTE: This function does not initialize timer/tick support. For timer
-/// services to be available xos_start_system_timer() must be called.
-///
-/// NOTE: xos_start() and xos_start_main() are exclusive, both cannot be
-/// called within the same application.
-///
-/// \param flags Currently unused (pass 0).
-///
-/// \return Does not return.
-///
-//-----------------------------------------------------------------------------
-void
-xos_start(uint32_t flags);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Initialize XOS thread support and create init (main) thread.
-///
-/// Must be called from main() before calling any other thread function.
-/// This function converts the caller into the 'main' or 'init' thread, and
-/// returns to the caller after completing initialization.
-///
-/// NOTE: This function does not initialize timer/tick support. For timer
-/// services to be available xos_start_system_timer() must be called.
-///
-/// NOTE: xos_start_main() and xos_start() are exclusive, both cannot be
-/// called within the same application.
-///
-/// \param name Name of main thread (see xos_thread_create()).
-///
-/// \param priority Initial priority of main thread.
-///
-/// \param flags Currently unused (pass 0).
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-void
-xos_start_main(const char * name, int8_t priority, uint32_t flags);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Per-thread stats structure.
-/// Note that the CPU use % is approximate, both because of cycle counting
-/// and because of integer division. So all the threads' CPU % will not add
-/// up to exactly 100%.
-///
-//-----------------------------------------------------------------------------
-typedef struct XosThreadStats {
- XosThread * thread; ///< Thread handle (or pseudo-handle)
- uint32_t cpu_pct; ///< CPU use % for this thread
- uint32_t normal_switches; ///< Number of non-preemptive switches.
- uint32_t preempt_switches; ///< Number of preemptive switches.
- uint64_t cycle_count; ///< Number of cycles consumed.
-} XosThreadStats;
-
-
-//-----------------------------------------------------------------------------
-// Thread pseudo-handles.
-//-----------------------------------------------------------------------------
-#define XOS_THD_STATS_IDLE ((XosThread *) 1)
-#define XOS_THD_STATS_INTR ((XosThread *) 2)
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get the thread statistics for the specified thread. Statistics are only
-/// available if XOS_OPT_STATS has been enabled. Otherwise, the function
-/// will return XOS_OK, but the structure contents will be undefined.
-///
-/// \param thread Handle of thread being queried. The following
-/// special pseudo-handles can be used:
-/// - XOS_THD_STATS_IDLE -- stats for idle thread
-/// - XOS_THD_STATS_INTR -- stats for interrupt processing
-///
-/// \param stats Pointer to XosThreadStats struct to be filled in.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-/// NOTE: Can be called from interrupt context.
-/// NOTE: This call will not fill in the "thread" and "cpu_pct" fields in the
-/// "stats" structure. The thread handle is already known, and calculating the
-/// CPU loading can take quite a bit of time so is not done here.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_thread_get_stats(XosThread * thread, XosThreadStats * stats);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get CPU loading statistics for the system. This function computes the CPU
-/// percentage use for all threads in the system (including the idle thread and
-/// the 'interrupt thread' (interrupt context). It also returns the cycle count
-/// and number of context switches for each thread.
-/// Statistics are only available if XOS_OPT_STATS has been enabled.
-/// Otherwise, the function will return XOS_OK, but the structure contents will
-/// be undefined.
-///
-/// IMPORTANT: The entry for interrupt context does not contain a real thread
-/// handle. It uses the pseudo-handle XOS_THD_STATS_INTR to indicate that this
-/// entry reports interrupt statistics. This pseudo-handle cannot be used for
-/// any other thread operations or queries.
-///
-/// NOTE: This function disables interrupts while traversing the thread list.
-/// It does not leave interrupts disabled during the computations, as that can
-/// take a fair amount of time.
-///
-/// \param stats Pointer to an array of XosThreadStats structures.
-/// The array must be large enough to accommodate all
-/// threads in the system.
-///
-/// \param size The number of elements available in the array. If
-/// this is smaller than the number of threads plus one
-/// (for the interrupt context) then XOS_ERR_INVALID_PARAMETER
-/// will be returned and '*size' will be set to the
-/// minimum number of elements required. On a successful
-/// return, '*size' is set to the number of elements
-/// actually filled in.
-///
-/// \param reset If nonzero, then thread stats counters are reset
-/// after reading. This is useful if you want to track
-/// the stats so as to get a better idea of current
-/// system loading. E.g. calling this function once a
-/// second with 'reset' nonzero will provide CPU load
-/// information for the last second on each call.
-///
-/// \return Returns XOS_OK on success, else error code. In particular,
-/// XOS_ERR_INVALID_PARAMETER will be returned if the output buffer
-/// is too small.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_get_cpu_load(XosThreadStats * stats, int32_t * size, int32_t reset);
-
-
-#ifdef _XOS_INCLUDE_INTERNAL_
-
-// Signature of valid thread object
-#define XOS_THREAD_SIG 0x54485244
-
-
-// Extern functions
-void
-xos_init(void);
-
-bool
-xos_init_done(void);
-
-bool
-xos_started(void);
-
-int32_t
-xos_schedule(XosThread * curr_thread);
-
-void
-xos_q_remove(XosThreadQueue * queue, XosThread * thread);
-
-XosThread *
-xos_q_pop(XosThreadQueue * queue);
-
-int32_t
-xos_wake_queue(XosThreadQueue * queue, const char * expected_cause, int32_t wake_value);
-
-// Well known block causes
-extern const char * const xos_blkon_idle; // (for idle thread only)
-extern const char * const xos_blkon_suspend;
-extern const char * const xos_blkon_delay;
-extern const char * const xos_blkon_exited;
-extern const char * const xos_blkon_join;
-extern const char * const xos_blkon_event;
-extern const char * const xos_blkon_condition;
-extern const char * const xos_blkon_mutex;
-extern const char * const xos_blkon_sem;
-extern const char * const xos_blkon_msgq;
-
-
-//-----------------------------------------------------------------------------
-// Blocks the current active thread.
-//
-// Currently, this can be called from an interrupt handler to block the thread
-// that was interrupted. Note that in interrupt context the current thread can
-// already be in the blocked state, due to a previous call to this function.
-// Can be called with interrupts enabled.
-//
-// block_cause Reason for blocking.
-//
-// block_queue Queue on to which this thread should be pushed once it
-// is blocked. Can be NULL.
-//
-// must_schedule If nonzero, then forces a scheduling operation to pick
-// the next thread to run, even if there are ready threads
-// at the same priority level as the blocked thread.
-//
-// use_priority If nonzero, then the blocked thread will be queued in
-// priority order in the specified block queue. If zero,
-// the thread is queued in FIFO order. If no queue has
-// been specified, this parameter is ignored.
-//
-// Returns: The value passed by xos_thread_wake().
-//-----------------------------------------------------------------------------
-int32_t
-xos_block(const char * block_cause,
- XosThreadQueue * block_queue,
- int32_t must_schedule,
- int32_t use_priority);
-
-
-//-----------------------------------------------------------------------------
-// Unblocks the specified blocked thread and puts it at the tail end of its
-// ready queue. Schedules it if it is higher priority than the current thread.
-// No effect if the thread is not blocked with the specified cause.
-//
-// thread The thread to wake up (make ready).
-//
-// expected_cause The expected block cause of the thread. Thread will be
-// woken only if its block cause matches this cause, or if
-// expected_cause is zero.
-//
-// wake_value The value to be passed to the woken thread as a return
-// value from xos_thread_block().
-//
-// Returns: nothing.
-//
-// The target thread can be woken at a different priority by changing its
-// priority while the thread is blocked.
-// Can be called with interrupts enabled. Can be called in interrupt context.
-//-----------------------------------------------------------------------------
-void
-xos_thread_wake(XosThread * thread, const char * expected_cause, int32_t wakevalue);
-
-
-//-----------------------------------------------------------------------------
-// Function to init C library per-thread and reentrancy support.
-//-----------------------------------------------------------------------------
-#if XOS_OPT_THREAD_SAFE_CLIB
-void
-xos_clib_init(void);
-
-void
-xos_clib_thread_init(XosThread * thread);
-
-void
-xos_clib_thread_cleanup(XosThread * thread);
-#endif
-
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __XOS_THREAD_H__
-
diff --git a/components/esp32/include/xtensa/xos_timer.h b/components/esp32/include/xtensa/xos_timer.h
deleted file mode 100644
index 0d89a21929..0000000000
--- a/components/esp32/include/xtensa/xos_timer.h
+++ /dev/null
@@ -1,592 +0,0 @@
-/** @file */
-
-// xos_timer.h - XOS Timer API interface and data structures.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// NOTE: Do not include this file directly in your application. Including
-// xos.h will automatically include this file.
-
-
-#ifndef __XOS_TIMER_H__
-#define __XOS_TIMER_H__
-
-#include "xos_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-//-----------------------------------------------------------------------------
-///
-/// Function pointer type for timer callbacks.
-///
-//-----------------------------------------------------------------------------
-typedef void (XosTimerFunc)(void * arg);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Timer event structure. Used to track pending timer events.
-///
-//-----------------------------------------------------------------------------
-typedef struct XosTimer {
- struct XosTimer * next; ///< Pointer to next event in list.
- uint64_t when; ///< Time (clock cycles) at which to trigger.
- uint64_t delta; ///< Delta for next re-trigger, 0 if none.
- XosTimerFunc * fn; ///< Function to call when timer expires.
- void * arg; ///< Argument to pass to called function.
- bool active; ///< Set if active (in some list of events).
-#if XOS_OPT_TIMER_WAIT
- XosThreadQueue waitq; ///< Queue of threads waiting on this timer.
-#endif
-#if XOS_TIMER_DEBUG
- uint32_t signature;
-#endif
-} XosTimer;
-
-
-//-----------------------------------------------------------------------------
-// Extern declarations.
-//-----------------------------------------------------------------------------
-
-// System clock frequency in cycles per second.
-extern uint32_t xos_clock_freq;
-
-
-///@{
-//-----------------------------------------------------------------------------
-// Functions to convert from clock cycles to time units and vice versa.
-//
-// Note that these are integer conversions so for example a cycle count of less
-// than one second will convert to zero seconds.
-//-----------------------------------------------------------------------------
-
-/// Converts CPU cycles to time in seconds.
-///
-/// \param cycles Number of CPU cycles.
-///
-/// \return Equivalent number of seconds (truncated to integer).
-static inline uint64_t
-xos_cycles_to_secs(uint64_t cycles)
-{
- return cycles / xos_clock_freq;
-}
-
-/// Converts CPU cycles to time in milliseconds.
-///
-/// \param cycles Number of CPU cycles.
-///
-/// \return Equivalent number of milliseconds (truncated to integer).
-static inline uint64_t
-xos_cycles_to_msecs(uint64_t cycles)
-{
- return (cycles * 1000) / xos_clock_freq;
-}
-
-/// Converts CPU cycles to time in microseconds.
-///
-/// \param cycles Number of CPU cycles.
-///
-/// \return Equivalent number of microseconds (truncated to integer).
-static inline uint64_t
-xos_cycles_to_usecs(uint64_t cycles)
-{
- return (cycles * 1000000) / xos_clock_freq;
-}
-
-/// Converts time in seconds to CPU cycle count.
-///
-/// \param secs Number of seconds.
-///
-/// \return Equivalent number of CPU cycles.
-static inline uint64_t
-xos_secs_to_cycles(uint64_t secs)
-{
- return secs * xos_clock_freq;
-}
-
-/// Converts time in milliseconds to CPU cycle count.
-///
-/// \param msecs Number of milliseconds.
-///
-/// \return Equivalent number of CPU cycles.
-static inline uint64_t
-xos_msecs_to_cycles(uint64_t msecs)
-{
- return (msecs * xos_clock_freq) / 1000;
-}
-
-/// Converts time in microseconds to CPU cycle count.
-///
-/// \param usecs Number of microseconds.
-///
-/// \return Equivalent number of CPU cycles.
-static inline uint64_t
-xos_usecs_to_cycles(uint64_t usecs)
-{
- return (usecs * xos_clock_freq) / 1000000;
-}
-///@}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set system clock frequency. This is expected to be set only once, and only
-/// if the clock frequency is not known at compile time.
-///
-/// \param freq Frequency in cycles per second.
-///
-/// \return Returns nothing.
-///
-//-----------------------------------------------------------------------------
-static inline void
-xos_set_clock_freq(uint32_t freq)
-{
- xos_clock_freq = freq;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get current system clock frequency.
-///
-/// \return Returns current system clock frequency in cycles per second.
-///
-//-----------------------------------------------------------------------------
-static inline uint32_t
-xos_get_clock_freq()
-{
- return xos_clock_freq;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Initialize timer support and start the system timer.
-/// This function must be called before calling any other timer function.
-///
-/// NOTE: The smaller the tick period, the more precisely delays can be
-/// specified using timers. However, we also need to make the tick period
-/// large enough to allow time both to execute the tick timer interrupt handler
-/// and for the application to make reasonable forward progress. If tick_period
-/// is too small, the timer interrupt may re-trigger before the timer interrupt
-/// handler has returned to the application, thus keeping the processor busy in
-/// constantly executing the timer interrupt handler without leaving any cycles
-/// for the application. Or, the application might get some cycles but only a
-/// fraction of what is spent in the timer interrupt handler, thus severely
-/// impacting application performance.
-///
-/// The exact number of cycles needed to execute the timer interrupt handler
-/// is not specified here. It depends on many factors (e.g. use of caches,
-/// various processor configuration options, etc) and can vary by orders of
-/// magnitude. Also note that the time to execute this handler is variable:
-/// when timers expire upon a given tick timer interrupt, their respective
-/// timer handler functions are called from within the interrupt handler.
-///
-/// \param timer_num Which Xtensa timer to use (0..2). This timer
-/// must exist and be configured at level 1 or at a
-/// medium-priority interrupt level (<=EXCM_LEVEL).
-/// If 'timer_num' is -1, then this function will
-/// automatically choose the highest priority timer
-/// that is suitable for use. This value will be
-/// passed to xos_system_timer_select().
-///
-/// \param tick_period Number of clock (CCOUNT) cycles between ticks.
-/// Must range between 0 and UINT32_MAX.
-/// Zero is used to specify dynamic tick (tickless)
-/// mode.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_start_system_timer(int32_t timer_num, uint32_t tick_period);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get the timer number of the system timer. Useful mainly when XOS has been
-/// allowed to choose its own timer via xos_start_system_timer(). Not valid if
-/// called before the system timer has been started.
-///
-/// \return Returns one of XOS_SYS_TIMER_0, XOS_SYS_TIMER_1, XOS_SYS_TIMER_2
-/// or XOS_SYS_TIMER_EXTERNAL, or XOS_SYS_TIMER_NONE.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_get_system_timer_num(void);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Initialize timer object.
-///
-/// \param timer Pointer to timer event structure.
-///
-/// \return Returns nothing.
-///
-/// NOTE: This function should not be called on a timer object once it has
-/// been activated.
-///
-//-----------------------------------------------------------------------------
-void xos_timer_init(XosTimer * timer);
-
-
-//-----------------------------------------------------------------------------
-// Flags for xos_timer_start().
-//-----------------------------------------------------------------------------
-#define XOS_TIMER_DELTA 0x0000
-#define XOS_TIMER_PERIODIC 0x0001
-#define XOS_TIMER_ABSOLUTE 0x0002
-#define XOS_TIMER_FROM_NOW 0x0000
-#define XOS_TIMER_FROM_LAST 0x0010
-
-
-//-----------------------------------------------------------------------------
-///
-/// Start the timer, and when the timer expires, call the specified function
-/// (invoke (*fn)(arg)). If the timer is periodic, it will be automatically
-/// restarted when it expires.
-///
-/// The specified timer event structure must have been initialized before
-/// first use by calling xos_timer_init().
-///
-/// The callback function will be called in an interrupt context. Hence it is
-/// NOT safe to use any coprocessors in the function, including the FPU. If a
-/// coprocessor must be used, then its state must be saved and restored across
-/// its use.
-///
-/// NOTE: If you are using the timer only to wait on (via xos_timer_wait())
-/// then it is not necessary to specify a callback function. You should pass
-/// NULL for the callback function and zero for the callback argument.
-///
-/// \param timer Pointer to timer event structure. Must have been
-/// initialized. May be active or not.
-///
-/// \param when When to call the function (see flags).
-///
-/// \param flags Set of option flags XOS_TIMER_* \n
-/// The following flags are mutually exclusive:
-/// - XOS_TIMER_DELTA -- when is number of cycles from
-/// [see below] (default)
-/// - XOS_TIMER_PERIODIC -- when is number of cycles
-/// from [see below], and timer continually
-/// re-triggers at that interval
-/// - XOS_TIMER_ABSOLUTE -- when is absolute value of
-/// cycle count \n
-/// \n
-/// The following flags are mutually exclusive:
-/// - XOS_TIMER_FROM_NOW -- *DELTA and *PERIODIC are
-/// relative to now (default)
-/// - XOS_TIMER_FROM_LAST -- *DELTA and *PERIODIC are
-/// relative to the timer event's last specified expiry
-/// time (usually in the future if active, in the past
-/// if not, absolute 0 if was never activated).
-///
-/// \param func Function to call (called in timer interrupt context).
-/// This argument is optional. Specify NULL if no function
-/// is to be called.
-///
-/// \param arg Argument passed to callback function. Only relevant if
-/// 'func' is not NULL.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_timer_start(XosTimer * timer,
- uint64_t when,
- uint32_t flags,
- XosTimerFunc * func,
- void * arg);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Stop the timer and remove it from the list of active timers. Has no effect
-/// if the timer is not active. Any waiting threads are woken up.
-///
-/// The timer structure must have been initialized at least once, else its
-/// contents are undefined and can lead to unpredictable results.
-///
-/// \param timer Pointer to timer object.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_timer_stop(XosTimer * timer);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Reset and restart the timer.
-///
-/// The timer is reset to go off at time "when" from now. If the timer was not
-/// active, it will be activated. If the timer was active, it will be restarted.
-/// If the timer is periodic, the period will be set to "when".
-/// The timer object must have been initialized at some point before this call.
-///
-/// \param timer Pointer to timer object.
-///
-/// \param when Number of cycles from now that the timer will expire.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_timer_restart(XosTimer * timer, uint64_t when);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Check if the timer is active. The timer is active if it has been started
-/// and not yet expired or canceled.
-///
-/// \param timer Pointer to timer object.
-///
-/// \return Returns non-zero if the timer is active, else zero.
-///
-//-----------------------------------------------------------------------------
-static inline int32_t
-xos_timer_is_active(XosTimer * timer)
-{
- return timer ? timer->active : 0;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get the repeat period for a periodic timer. For a one-shot timer this will
-/// return zero. The period is reported in system clock cycles.
-///
-/// \param timer Pointer to timer object.
-///
-/// \return Returns period in cycles, or zero for non-periodic timers.
-///
-//-----------------------------------------------------------------------------
-static inline uint64_t
-xos_timer_get_period(XosTimer * timer)
-{
- return timer ? timer->delta : 0;
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Set the repeat period for a periodic timer. The period must be specified
-/// in system clock cycles.
-///
-/// If the timer is active, the change in period does not take effect until
-/// the timer expires at least once after this call.
-/// Note that setting a period of zero will effectively turn a periodic timer
-/// into a one-shot timer. Similarly, a one-shot timer can be turned into a
-/// periodic timer.
-///
-/// \param timer Pointer to timer object.
-///
-/// \param period Repeat period in system clock cycles.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_timer_set_period(XosTimer * timer, uint64_t period);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Get the current system cycle count. This accounts for the periodic rollover
-/// of the 32-bit CCOUNT cycle counter and returns a 64-bit value.
-///
-/// \return Returns the current system cycle count.
-///
-//-----------------------------------------------------------------------------
-static inline uint64_t
-xos_get_system_cycles(void)
-{
- extern uint64_t xos_system_cycles;
- extern uint32_t xos_last_ccount;
-
- // xos_last_ccount was updated when xos_system_cycles was last updated.
- // We need to add in the number of cycles elapsed since then.
- return xos_system_cycles + (xos_get_ccount() - xos_last_ccount);
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Put calling thread to sleep for at least the specified number of cycles.
-/// The actual number of cycles spent sleeping may be larger depending upon
-/// the granularity of the system timer. Once the specified time has elapsed
-/// the thread will be woken and made ready.
-///
-/// \param cycles Number of system clock cycles to sleep.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_thread_sleep(uint64_t cycles);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Put calling thread to sleep for at least the specified number of msec.
-/// The actual amount of time spent sleeping may be larger depending upon
-/// the granularity of the system timer. Once the specified time has elapsed
-/// the thread will be woken and made ready.
-///
-/// \return msecs The number of milliseconds to sleep.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-static inline int32_t
-xos_thread_sleep_msec(uint64_t msecs)
-{
- return xos_thread_sleep(xos_msecs_to_cycles(msecs));
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Put calling thread to sleep for at least the specified number of usec.
-/// The actual amount of time spent sleeping may be larger depending upon
-/// the granularity of the system timer. Once the specified time has elapsed
-/// the thread will be woken and made ready.
-///
-/// \return usecs The number of microseconds to sleep.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-static inline int32_t
-xos_thread_sleep_usec(uint64_t usecs)
-{
- return xos_thread_sleep(xos_usecs_to_cycles(usecs));
-}
-
-
-//-----------------------------------------------------------------------------
-///
-/// Wait on a timer until it expires or is cancelled. The calling thread will
-/// be blocked. The timer must be active.
-/// NOTE: This operation is only available if XOS_OPT_TIMER_WAIT is set
-/// to 1 in the configuration options.
-///
-/// \param timer Pointer to timer object.
-///
-/// \return Returns XOS_OK on normal timeout, else an error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_timer_wait(XosTimer * timer);
-
-
-//-----------------------------------------------------------------------------
-// System timer control interface.
-//-----------------------------------------------------------------------------
-
-
-//-----------------------------------------------------------------------------
-// Defines for system timer ID.
-//-----------------------------------------------------------------------------
-#define XOS_SYS_TIMER_0 0 ///< Internal timer 0
-#define XOS_SYS_TIMER_1 1 ///< Internal timer 1
-#define XOS_SYS_TIMER_2 2 ///< Internal timer 2
-#define XOS_SYS_TIMER_EXTERNAL -2 ///< External timer
-#define XOS_SYS_TIMER_NONE -1 ///< No system timer selected
-
-
-//-----------------------------------------------------------------------------
-///
-/// This function handles XOS timer tick processing. It must be called by the
-/// timer interrupt handler on every timer interrupt. This function computes
-/// the time to the next tick and sets it up by calling xos_system_timer_set().
-///
-//-----------------------------------------------------------------------------
-void
-xos_tick_handler(void);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Selects the timer to use. The selection may be one of the internal timers
-/// or an external timer. The default implementation selects an internal timer.
-/// This function can be overridden to provide custom timer processing or to
-/// support an external timer.
-///
-/// \param timer_num The internal timer number to select (0-2) or
-/// -1 to auto-select a timer. This parameter can
-/// be ignored by custom implementations that use
-/// an external timer.
-///
-/// \param psel Pointer to a location where the selected timer
-/// ID must be returned. The timer ID must be one
-/// of XOS_SYS_TIMER_0, XOS_SYS_TIMER_1, XOS_SYS_TIMER_2
-/// or XOS_SYS_TIMER_EXTERNAL.
-///
-/// \return Returns XOS_OK on success, else error code.
-///
-//-----------------------------------------------------------------------------
-int32_t
-xos_system_timer_select(int32_t timer_num, int32_t *psel);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Starts the system timer and sets up the first interrupt. This function can
-/// be overridden to provide custom timer processing or to support an external
-/// timer.
-///
-/// \param cycles The number of CPU cycles from now when the
-/// first interrupt must occur.
-///
-//-----------------------------------------------------------------------------
-void
-xos_system_timer_init(uint32_t cycles);
-
-
-//-----------------------------------------------------------------------------
-///
-/// Sets the next trigger value of the system timer. The parameter 'cycles' is
-/// the number of CPU cycles from now when the interrupt must occur.
-/// This function can be overridden to provide custom timer processing or to
-/// support an external timer.
-///
-/// \param cycles The number of CPU cycles from now when the
-/// next interrupt must occur.
-///
-//-----------------------------------------------------------------------------
-void
-xos_system_timer_set(uint32_t cycles);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __XOS_TIMER_H__
-
diff --git a/components/esp32/include/xtensa/xos_types.h b/components/esp32/include/xtensa/xos_types.h
deleted file mode 100644
index a913b94a23..0000000000
--- a/components/esp32/include/xtensa/xos_types.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/** @file */
-// xos_types.h - XOS type definitions.
-
-// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// NOTE: Do not include this file directly in your application. Including
-// xos.h will automatically include this file.
-
-
-#ifndef __XOS_TYPES_H__
-#define __XOS_TYPES_H__
-
-#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include
-
-//-----------------------------------------------------------------------------
-// The following are defined here because of the variations in the C libraries
-// that we need to work with.
-// - Not all of them have stdbool.h
-// - Not all of them define NULL as (void *)0
-//-----------------------------------------------------------------------------
-
-
-//-----------------------------------------------------------------------------
-///
-/// XOS define for NULL value. This makes the NULL value independent of the
-/// C library (not all of them define NULL the same way).
-///
-//-----------------------------------------------------------------------------
-#define XOS_NULL ((void *)0)
-
-
-//-----------------------------------------------------------------------------
-///
-/// XOS definition of 'bool' type. Some C libraries do not support stdbool.h.
-///
-//-----------------------------------------------------------------------------
-#ifndef bool
-#define bool int8_t
-#define false 0 ///< XOS definition of 'false'
-#define true 1 ///< XOS definition of 'true'
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
-
-#endif // __XOS_TYPES_H__
-
diff --git a/components/esp32/include/xtensa/xt_perfmon.h b/components/esp32/include/xtensa/xt_perfmon.h
deleted file mode 100644
index 959052b164..0000000000
--- a/components/esp32/include/xtensa/xt_perfmon.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Customer ID=11656; Build=0x5f626; Copyright (c) 2012 by Tensilica Inc. ALL RIGHTS RESERVED.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef __XT_PERFMON_H__
-#define __XT_PERFMON_H__
-
-#include
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef int counter_id_t;
-
-/* xt_perf_init
-
- Initialize the performance monitor library. Ordinarily, this
- function is called automatically via the .init section. If your
- environment does not support the .init section, you will need to
- call this function from your code.
-*/
-
-extern void xt_perf_init(void);
-
-/* xt_perf_enable
-
- Turn on the performance monitor. Ordinarily, counting is off by
- default. If you turn off performance monitor using xt_perf_disable or
- by call to a function that disables performance monitor, you can turn
- it on again via this function.
-*/
-
-extern void xt_perf_enable(void);
-
-/* xt_perf_disable
-
- Turn off the performance monitor. If you want to suspend counting
- events for a portion of your code, use this function and then call
- xt_perf_enable when you want to start again.
-*/
-
-extern void xt_perf_disable(void);
-
-/* xt_perf_clear
-
- Disable performance monitor and clear all initialized hardware counters.
- All counter ids are invalid after call to this function and all hardware
- counters available for initialization.
-*/
-
-extern void xt_perf_clear (void);
-
-/* xt_perf_counters_num
-
- Returns number of free hardware performance counters. After call to xt_perf_clear
- all counters are free and available for initialization. With each successful
- xt_perf_init_counter/xt_perf_init_event call this number is decreasing until
- no free counters available.
-*/
-
-extern int xt_perf_counters_num (void);
-
-/* xt_perf_init_counter32
-
- Setup 32 bit performance counter. This function disables performance monitor
- if it was enabled.
-
- Returns zero based counter id on success or negative value if failed.
- This function may fail if there is insufficient number of free hardware
- counters or function arguments are invalid.
-
- The counter id returned on success can be used with xt_perf_reset_counter
- and xt_perf_counter32 functions.
-
- - events group, one of XTPERF_CNT constants defined in
- xt_perf_consts.h;
- - events mask for selected group. Mask bit fields for each
- selector defined with XTPERF_MASK prefix in xt_perf_consts.h;
- - specifies interrupt levels at which to count events;
- if trace_level is greater or equal to zero events are
- counted only at interrupt levels below or equal to
- trace_level; if trace_level is negative events are
- counted only at (-trace_level) interrupt level or higher.
-*/
-
-
-extern counter_id_t xt_perf_init_counter32 ( unsigned int selector,
- unsigned int mask,
- int trace_level);
-
-/* xt_perf_init_counter64
-
- Setup 64 bit performance counter. Library emulates 64 bit counters by handling
- profiling interrupt and recording overflows of 32 bit hardware counters.
- This function disables performance monitor if it was enabled.
-
- Returns zero based counter id on success or negative value if failed.
- This function may fail if there is insufficient number of free hardware
- counters or function arguments are invalid.
-
- The counter id returned on success can be used with xt_perf_reset_counter
- and xt_perf_counter64 functions.
-
- - events group, one of XTPERF_CNT constants defined in
- xt_perf_consts.h;
- - events mask for selected group. Mask bit fields for each
- selector defined with XTPERF_MASK prefix in xt_perf_consts.h;
- - specifies interrupt levels at which to count events;
- if trace_level is greater or equal to zero events are
- counted only at interrupt levels below or equal to
- trace_level; if trace_level is negative events are
- counted only at (-trace_level) interrupt level or higher.
-*/
-
-extern counter_id_t xt_perf_init_counter64 ( unsigned int selector,
- unsigned int mask,
- int trace_level);
-
-/* xt_perf_reset_counter
-
- Reset counter value to 0.
- Returns zero on success or non zero if failed.
-*/
-
-extern int xt_perf_reset_counter (counter_id_t counter_id);
-
-/* xt_perf_counter32
-
- Read 32 bit counter value.
-
- Returns zero if counter id is not valid.
-*/
-
-extern unsigned int xt_perf_counter32 (counter_id_t counter_id);
-
-/* xt_perf_counter64
-
- Read 64 bit counter value.
-
- Counter must be initialized using xt_perf_init_counter64 function.
-
- Returns zero if counter id is not valid.
-*/
-
-extern unsigned long long xt_perf_counter64 (counter_id_t counter_id);
-
- /* xt_perf_overflow32
-
- Read overflow flag of 32 bit counter. This flag is dropped when
- counter initialized or reset. Once counter overflows and wraps
- around the flag is set and stays set until counter reset.
-
- Returns negative value if counter id is invalid, zero if counter
- not overflowed, positive if in overflowed state.
- */
-
-extern int xt_perf_overflow32 (counter_id_t counter_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XT_PERFMON_H__ */
diff --git a/components/esp32/include/xtensa/xt_profiling.h b/components/esp32/include/xtensa/xt_profiling.h
deleted file mode 100644
index 650713a459..0000000000
--- a/components/esp32/include/xtensa/xt_profiling.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Customer ID=11656; Build=0x5f626; Copyright (c) 2005-2012 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-#ifndef __XT_PROFILER_H__
-#define __XT_PROFILER_H__
-
-#include
-
-#if XCHAL_NUM_PERF_COUNTERS
-/* Performance monitor counters constants */
-#include
-
-#endif /* XCHAL_NUM_PERF_COUNTERS */
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* This file defines an interface that allows a program being profiled
- to control when and how it is profiled, whether it is running under
- the instruction set simulator or under the hardware profiler.
-
- Both ISS and HWP implement this interface, although in different
- ways. Both also do the right thing if you don't call any of these
- functions.
-*/
-
-
-/*
-xt_profile_init
-
- ISS: a no op.
-
- HWP: Initialize the profiler. Ordinarily, this function is called
- automatically via the .init section. If your environment does not
- support the .init section, you will need to call this function
- by hand.
-*/
-extern void xt_profile_init(void);
-
-/*
-xt_profile_add_memory
-
- ISS: a no op.
-
- HWP:
- Makes "buf_size" bytes at "buf" available to the hardware profiler.
- This buffer should be initialized to zeros prior to this call.
-
- The hardware profiler has already estimated the amount of memory it needs,
- but under certain circumstances may still run out of memory. If so, you can
- provide more memory with this routine.
-
-*/
-extern void xt_profile_add_memory(void * buf, unsigned int buf_size);
-
-
-/* xt_profile_enable
-
- Turn on the profiler. Ordinarily, profiling is on by default.
- If you turn off profiling using xt_profile_disable, You can turn
- it on again via this function.
-*/
-extern void xt_profile_enable(void);
-
-/* xt_profile_disable
-
- Turn off the profiler. If you don't want to profile a portion of your code,
- use this function and then xt_profile_enable when you want to start again.
-*/
-extern void xt_profile_disable(void);
-
-/* xt_profile_save_and_reset
-
- Save and reset the profiler's data.
- If there were errors, either during profiling or while attempting to
- write the data, no data will be written and this function will
- return non-zero.
-
-*/
-extern int xt_profile_save_and_reset(void);
-
-/* xt_profile_get_frequency
-
- ISS: always returns 1.
-
- HWP:
- Returns the number of cycles between samples for timer based profiler.
- In performance counters based profiler always returns 1.
-*/
-extern unsigned int xt_profile_get_frequency(void);
-
-/* xt_profile_set_frequency
-
- ISS: a no op.
-
- HWP:
- Set the number of cycles between samples for timer based profiler.
- Ignored in performance counters based profiler.
-
- sample frequency is the number of cycles to wait between samples. It should
- be a multiple of 1024.
-
- If you set the sample frequency to a different value than was passed in xt_profile_init,
- then the labels in the output will reflect the later frequency, even though some samples may
- have been taken at the earlier frequency. Typically this does not make a significant difference
- in the results if this function is called early enough.
-*/
-extern void xt_profile_set_frequency(unsigned int sample_frequency);
-
-/* xt_profile_num_errors
-
- ISS: always returns 0
-
- HWP:
- Returns the number of errors that occured while taking samples. Typically these
- are out of memory errors and you need to pass a bigger buffer to
- xt_profile_add_memory
-*/
-extern int xt_profile_num_errors(void);
-
-
-#if XCHAL_NUM_PERF_COUNTERS
-
-
-/* xt_profile_randomize
-
- ISS: not available
-
- HWP: Available in performance monitor based profiler.
-
- Turns on or off sampling period randomization mode. Period randomization
- helps to avoid aliasing problems when code being profiled is highly periodic.
- Profiler maintains same average sampling period but individual sampling
- steps may vary.
- Period randomization is turned off by default.
-
- - non zero turns randomization on,
- zero turns randomization off.
-*/
-
-extern void xt_profile_randomization(int value);
-
-/* xt_profile_config_clear
-
- ISS: not available
-
- HWP: Available in performance monitor based profiler.
-
- Stops profiling if it was enabled and clears performance counters
- parameters. Accumulated profile data stays in memory and will be
- saved when xt_profile_save_and_reset is called or at program exit.
- Number of configured performance counters is zero after this
- function call.
-*/
-
-extern void xt_profile_config_clear(void);
-
-
-/* xt_profile_config_num
-
- ISS: not available
-
- HWP: Available in performance monitor based profiler.
-
- Returns number of free performance counters.
-*/
-
-extern int xt_profile_config_num(void);
-
-
-/* xt_profile_config_counter error codes
-*/
-
-#define XTPROF_ERR_OUT_OF_MEM -1
-#define XTPROF_ERR_INVALID_ARGS -2
-#define XTPROF_ERR_NOT_ENOUGH_COUNTERS -3
-#define XTPROF_ERR_DEFUNCT -4
-
-/* xt_profile_config_counter
-
- ISS: not available
-
- HWP: Available in performance monitor based profiler.
-
- Allocating and initializing one or more performance counter for sampling.
- Even though event may require multiple performance counters allocated the
- profile data for event is merged and dumped into single gmon file.
- This function disables profiling if it was enabled.
-
- Returns 0 on success, non zero if failed:
- XTPROF_ERR_OUT_OF_MEM - memory allocation failed;
- XTPROF_ERR_INVALID_ARGS - invalid function parameters;
- XTPROF_ERR_NOT_ENOUGH_COUNTERS - not enough free performance counters available;
- XTPROF_ERR_DEFUNCT - profiling is disabled because of previous errors
- (xt_profile_num_errors() is non zero)
-
- - events group, one of XTPERF_CNT constants defined in xt_perf_consts.h
- - events mask for selected group. Mask bit fields for each
- selector defined with XTPERF_MASK prefix in xt_perf_consts.h
- - specifies interrupt levels at which to take samples;
- if trace_level is greater or equal to zero samples are
- taken only at interrupt levels below or equal to
- trace_level; if trace_level is negative samples are taken
- only at (-trace_level) interrupt level or higher.
- - sampling period; 1 - record every event, 2 - record every
- other event and so on;
- Please note - there is overhead associated with events recording,
- high frequency events may produce incorrect profile when period
- is too small.
-*/
-
-extern int xt_profile_config_counter ( unsigned int selector,
- unsigned int mask,
- int trace_level,
- unsigned int period);
-
-
-
-#endif /* XCHAL_NUM_PERF_COUNTERS */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XT_PROFILER_H__ */
diff --git a/components/esp32/include/xtensa/xt_reftb.h b/components/esp32/include/xtensa/xt_reftb.h
deleted file mode 100644
index 358c39f740..0000000000
--- a/components/esp32/include/xtensa/xt_reftb.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Customer ID=11656; Build=0x5f626; Copyright (c) 2009-2013 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of
- * Tensilica Inc. They may be adapted and modified by bona fide
- * purchasers for internal use, but neither the original nor any
- * adapted or modified version may be disclosed or distributed to
- * third parties in any manner, medium, or form, in whole or in part,
- * without the prior written consent of Tensilica Inc.
- *
- * This software and its derivatives are to be executed solely on
- * products incorporating a Tensilica processor.
- */
-
-// Utility routines for returning pass/fail status in HW simulations
-
-#ifndef XT_REF_TESTBENCH_H
-#define XT_REF_TESTBENCH_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Exit routines for HW simulation
-extern int diag_pass();
-extern int diag_fail();
-
-// Set exit status for HW simulation
-int set_diag_status(int stat);
-
-// Setup for user power toggling
-extern int setup_power_toggle();
-
-// Return exit status location
-extern unsigned int* testbench_exit_location();
-// Return power toggle location
-extern unsigned int* testbench_power_toggle_location();
-
-
-// Change exit status location
-// You must also change the plusarg "+DVMagicExit" sent to the HW simulator
-// or change the argument "--exit_location" sent to the ISS
-extern unsigned int* set_testbench_exit_location(unsigned int*);
-// Change power toggle location
-// You must also change the plusarg "+DVPowerLoc" sent to the HW simulator
-extern unsigned int* set_testbench_power_toggle_location(unsigned int*);
-
-// Exit routines with status message
-//
-static inline
-int pass(const char *msg)
-{
- return diag_pass();
-}
-
-static inline
-int fail(const char *msg)
-{
- return diag_fail();
-}
-
-#define POWER_TOGGLE_ON 1
-#define POWER_TOGGLE_OFF 0
-
-// Routine to turn on and off power toggle
-// Does a magic write that Monitors.v intercepts and appropriately turns
-// SAIF dumping on and offf
-//
-extern volatile unsigned int *_reftb_power_toggle;
-
-__attribute__ ((always_inline))
-static inline
-int set_power_toggle(int val)
-{
-#ifdef __XTENSA__
- *_reftb_power_toggle = val;
-#endif
- return val;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // XT_REF_TESTBENCH_H
-
diff --git a/components/esp32/include/xtensa/xtav110.h b/components/esp32/include/xtensa/xtav110.h
deleted file mode 100644
index 23421f0b74..0000000000
--- a/components/esp32/include/xtensa/xtav110.h
+++ /dev/null
@@ -1,313 +0,0 @@
-/* Copyright (c) 2007-2013 by Tensilica Inc. ALL RIGHTS RESERVED.
-/ These coded instructions, statements, and computer programs are the
-/ copyrighted works and confidential proprietary information of Tensilica Inc.
-/ They may not be modified, copied, reproduced, distributed, or disclosed to
-/ third parties in any manner, medium, or form, in whole or in part, without
-/ the prior written consent of Tensilica Inc.
-*/
-
-/* xtav110.h - Xtensa Avnet LX110 (XT-AV110) board specific definitions */
-
-#ifndef _INC_XTAV110_H_
-#define _INC_XTAV110_H_
-
-#include
-#include
-
-#define XTBOARD_NAME "XT-AV110"
-
-
-/*
- * Default assignment of XTAV110 devices to external interrupts.
- */
-
-/* Ethernet interrupt: */
-#ifdef XCHAL_EXTINT1_NUM
-#define ETHERNET_INTNUM XCHAL_EXTINT1_NUM
-#define ETHERNET_INTLEVEL XCHAL_EXTINT1_LEVEL
-#define ETHERNET_INTMASK XCHAL_EXTINT1_MASK
-#else
-#define ETHERNET_INTMASK 0
-#endif
-
-/* UART interrupt: */
-#ifdef XCHAL_EXTINT0_NUM
-#define UART16550_INTNUM XCHAL_EXTINT0_NUM
-#define UART16550_INTLEVEL XCHAL_EXTINT0_LEVEL
-#define UART16550_INTMASK XCHAL_EXTINT0_MASK
-#else
-#define UART16550_INTMASK 0
-#endif
-
-/* Audio output interrupt (I2S transmitter FIFO): */
-#ifdef XCHAL_EXTINT2_NUM
-#define AUDIO_I2S_OUT_INTNUM XCHAL_EXTINT2_NUM
-#define AUDIO_I2S_OUT_INTLEVEL XCHAL_EXTINT2_LEVEL
-#define AUDIO_I2S_OUT_INTMASK XCHAL_EXTINT2_MASK
-#else
-#define AUDIO_I2S_OUT_INTMASK 0
-#endif
-
-/* Audio input interrupt (I2S receiver FIFO): */
-#ifdef XCHAL_EXTINT3_NUM
-#define AUDIO_I2S_IN_INTNUM XCHAL_EXTINT3_NUM
-#define AUDIO_I2S_IN_INTLEVEL XCHAL_EXTINT3_LEVEL
-#define AUDIO_I2S_IN_INTMASK XCHAL_EXTINT3_MASK
-#else
-#define AUDIO_I2S_IN_INTMASK 0
-#endif
-
-/* I2C interrupt */
-#ifdef XCHAL_EXTINT4_NUM
-#define I2C_INTNUM XCHAL_EXTINT4_NUM
-#define I2C_INTLEVEL XCHAL_EXTINT4_LEVEL
-#define I2C_INTMASK XCHAL_EXTINT4_MASK
-#else
-#define I2C_INTMASK 0
-#endif
-
-/* USB interrupt */
-#ifdef XCHAL_EXTINT5_NUM
-#define USB_INTNUM XCHAL_EXTINT5_NUM
-#define USB_INTLEVEL XCHAL_EXTINT5_LEVEL
-#define USB_INTMASK XCHAL_EXTINT5_MASK
-#else
-#define USB_INTMASK 0
-#endif
-
-/*
- * Device addresses.
- *
- * Note: for endianness-independence, use 32-bit loads and stores for all
- * register accesses to Ethernet, UART and LED devices. Undefined bits
- * may need to be masked out if needed when reading if the actual register
- * size is smaller than 32 bits.
- *
- * Note: XTAV110 bus byte lanes are defined in terms of msbyte and lsbyte
- * relative to the processor. So 32-bit registers are accessed consistently
- * from both big and little endian processors. However, this means byte
- * sequences are not consistent between big and little endian processors.
- * This is fine for RAM, and for ROM if ROM is created for a specific
- * processor (and thus has correct byte sequences). However this may be
- * unexpected for Flash, which might contain a file-system that one wants
- * to use for multiple processor configurations (eg. the Flash might contain
- * the Ethernet card's address, endianness-independent application data, etc).
- * That is, byte sequences written in Flash by a core of a given endianness
- * will be byte-swapped when seen by a core of the other endianness.
- * Someone implementing an endianness-independent Flash file system will
- * likely handle this byte-swapping issue in the Flash driver software.
- */
-
-#define XTBOARD_FLASH_MAXSIZE 0x1000000 /* 16 MB */
-
-#ifdef XSHAL_IOBLOCK_BYPASS_PADDR
-
-/* Flash Memory: */
-# define XTBOARD_FLASH_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x08000000)
-
-/* FPGA registers: */
-# define XTBOARD_FPGAREGS_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D020000)
-
-/* Ethernet controller/transceiver SONIC SN83934: */
-# define ETHERNET_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D030000)
-
-
-/* UART National-Semi PC16550D: */
-# define UART16550_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D050000)
-
-/* I2S transmitter */
-# define AUDIO_I2S_OUT_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D080000)
-
-/* I2S receiver */
-# define AUDIO_I2S_IN_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D088000)
-
-/* I2C master */
-# define I2C_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D090000)
-
-/* SPI controller */
-# define SPI_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D0A0000)
-
-/* Display controller Sunplus SPLC780D, 4bit mode,
- * LCD Display MYTech MOC-16216B-B: */
-# define SPLC780D_4BIT_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D0C0000)
-
-/* USB Controller */
-# define USB_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D0D0000)
-
-/* Ethernet buffer: */
-# define ETHERNET_BUFFER_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D800000)
-
-#endif /* XSHAL_IOBLOCK_BYPASS_PADDR */
-
-/* These devices might be accessed cached: */
-#ifdef XSHAL_IOBLOCK_CACHED_PADDR
-# define XTBOARD_FLASH_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0x08000000)
-# define ETHERNET_BUFFER_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0x0D800000)
-#endif /* XSHAL_IOBLOCK_CACHED_PADDR */
-
-
-/*** Same thing over again, this time with virtual addresses: ***/
-
-#ifdef XSHAL_IOBLOCK_BYPASS_VADDR
-
-/* Flash Memory: */
-# define XTBOARD_FLASH_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x08000000)
-
-/* FPGA registers: */
-# define XTBOARD_FPGAREGS_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D020000)
-
-/* Ethernet controller/transceiver SONIC SN83934: */
-# define ETHERNET_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D030000)
-
-
-/* UART National-Semi PC16550D: */
-# define UART16550_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D050000)
-
-/* I2S transmitter */
-# define AUDIO_I2S_OUT_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D080000)
-
-/* I2S receiver */
-# define AUDIO_I2S_IN_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D088000)
-
-/* I2C master */
-# define I2C_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D090000)
-
-/* SPI controller */
-# define SPI_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D0A0000)
-
-/* Display controller Sunplus SPLC780D, 4bit mode,
- * LCD Display MYTech MOC-16216B-B: */
-# define SPLC780D_4BIT_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D0C0000)
-
-/* USB Controller */
-# define USB_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D0D0000)
-
-/* Ethernet buffer: */
-# define ETHERNET_BUFFER_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D800000)
-
-#endif /* XSHAL_IOBLOCK_BYPASS_VADDR */
-
-/* These devices might be accessed cached: */
-#ifdef XSHAL_IOBLOCK_CACHED_VADDR
-# define XTBOARD_FLASH_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0x08000000)
-# define ETHERNET_BUFFER_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0x0D800000)
-#endif /* XSHAL_IOBLOCK_CACHED_VADDR */
-
-
-/* System ROM: */
-#define XTBOARD_ROM_SIZE XSHAL_ROM_SIZE
-#ifdef XSHAL_ROM_VADDR
-#define XTBOARD_ROM_VADDR XSHAL_ROM_VADDR
-#endif
-#ifdef XSHAL_ROM_PADDR
-#define XTBOARD_ROM_PADDR XSHAL_ROM_PADDR
-#endif
-
-/* System RAM: */
-#define XTBOARD_RAM_SIZE XSHAL_RAM_SIZE
-#ifdef XSHAL_RAM_VADDR
-#define XTBOARD_RAM_VADDR XSHAL_RAM_VADDR
-#endif
-#ifdef XSHAL_RAM_PADDR
-#define XTBOARD_RAM_PADDR XSHAL_RAM_PADDR
-#endif
-#define XTBOARD_RAM_BYPASS_VADDR XSHAL_RAM_BYPASS_VADDR
-#define XTBOARD_RAM_BYPASS_PADDR XSHAL_RAM_BYPASS_PADDR
-
-
-
-/*
- * Things that depend on device addresses.
- */
-
-
-#define XTBOARD_CACHEATTR_WRITEBACK XSHAL_XT2000_CACHEATTR_WRITEBACK
-#define XTBOARD_CACHEATTR_WRITEALLOC XSHAL_XT2000_CACHEATTR_WRITEALLOC
-#define XTBOARD_CACHEATTR_WRITETHRU XSHAL_XT2000_CACHEATTR_WRITETHRU
-#define XTBOARD_CACHEATTR_BYPASS XSHAL_XT2000_CACHEATTR_BYPASS
-#define XTBOARD_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_DEFAULT
-
-#define XTBOARD_BUSINT_PIPE_REGIONS XSHAL_XT2000_PIPE_REGIONS
-#define XTBOARD_BUSINT_SDRAM_REGIONS XSHAL_XT2000_SDRAM_REGIONS
-
-
-/*
- * FPGA registers.
- * All these registers are normally accessed using 32-bit loads/stores.
- */
-
-/* Register offsets: */
-#define XTBOARD_DATECD_OFS 0x00 /* date code (read-only) */
-#define XTBOARD_CLKFRQ_OFS 0x04 /* clock frequency Hz (read-only) */
-#define XTBOARD_SYSLED_OFS 0x08 /* LEDs */
-#define XTBOARD_DIPSW_OFS 0x0C /* DIP switch bits (read-only) */
-#define XTBOARD_SWRST_OFS 0x10 /* software reset */
-
-/* Physical register addresses: */
-#ifdef XTBOARD_FPGAREGS_PADDR
-#define XTBOARD_DATECD_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_DATECD_OFS)
-#define XTBOARD_CLKFRQ_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_CLKFRQ_OFS)
-#define XTBOARD_SYSLED_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_SYSLED_OFS)
-#define XTBOARD_DIPSW_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_DIPSW_OFS)
-#define XTBOARD_SWRST_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_SWRST_OFS)
-#endif
-
-/* Virtual register addresses: */
-#ifdef XTBOARD_FPGAREGS_VADDR
-#define XTBOARD_DATECD_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_DATECD_OFS)
-#define XTBOARD_CLKFRQ_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_CLKFRQ_OFS)
-#define XTBOARD_SYSLED_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_SYSLED_OFS)
-#define XTBOARD_DIPSW_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_DIPSW_OFS)
-#define XTBOARD_SWRST_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_SWRST_OFS)
-/* Register access (for C code): */
-#define XTBOARD_DATECD_REG (*(volatile unsigned*) XTBOARD_DATECD_VADDR)
-#define XTBOARD_CLKFRQ_REG (*(volatile unsigned*) XTBOARD_CLKFRQ_VADDR)
-#define XTBOARD_SYSLED_REG (*(volatile unsigned*) XTBOARD_SYSLED_VADDR)
-#define XTBOARD_DIPSW_REG (*(volatile unsigned*) XTBOARD_DIPSW_VADDR)
-#define XTBOARD_SWRST_REG (*(volatile unsigned*) XTBOARD_SWRST_VADDR)
-#endif
-
-/* DATECD (date code; when core was built) bit fields: */
-/* BCD-coded month (01..12): */
-#define XTBOARD_DATECD_MONTH_SHIFT 24
-#define XTBOARD_DATECD_MONTH_BITS 8
-#define XTBOARD_DATECD_MONTH_MASK 0xFF000000
-/* BCD-coded day (01..31): */
-#define XTBOARD_DATECD_DAY_SHIFT 16
-#define XTBOARD_DATECD_DAY_BITS 8
-#define XTBOARD_DATECD_DAY_MASK 0x00FF0000
-/* BCD-coded year (2001..9999): */
-#define XTBOARD_DATECD_YEAR_SHIFT 0
-#define XTBOARD_DATECD_YEAR_BITS 16
-#define XTBOARD_DATECD_YEAR_MASK 0x0000FFFF
-
-/* SYSLED (system LED) bit fields: */
-
-/* LED control bits (off=0, on=1): */
-#define XTBOARD_SYSLED_USER_SHIFT 0
-#define XTBOARD_SYSLED_USER_BITS 2
-#define XTBOARD_SYSLED_USER_MASK 0x00000003
-
-/* DIP Switch SW5 (left=sw1=lsb=bit0, right=sw4=msb=bit3; off=0, on=1): */
-/* DIP switch bit fields (bit2/sw3 is reserved and presently unused): */
-#define XTBOARD_DIPSW_USER_SHIFT 0 /* labeled 1-2 (1=lsb) */
-#define XTBOARD_DIPSW_USER_BITS 2
-#define XTBOARD_DIPSW_USER_MASK 0x00000003
-#define XTBOARD_DIPSW_BOOT_SHIFT 3 /* labeled 8 (msb) */
-#define XTBOARD_DIPSW_BOOT_BITS 1
-#define XTBOARD_DIPSW_BOOT_MASK 0x00000008
-/* Boot settings: bit3/sw4, off=0, on=1 (this switch controls hardware): */
-#define XTBOARD_DIPSW_BOOT_RAM (0<
-
diff --git a/components/esp32/include/xtensa/xtav200.h b/components/esp32/include/xtensa/xtav200.h
deleted file mode 100644
index f3d837efa6..0000000000
--- a/components/esp32/include/xtensa/xtav200.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/* Copyright (c) 2007-2013 by Tensilica Inc. ALL RIGHTS RESERVED.
-/ These coded instructions, statements, and computer programs are the
-/ copyrighted works and confidential proprietary information of Tensilica Inc.
-/ They may not be modified, copied, reproduced, distributed, or disclosed to
-/ third parties in any manner, medium, or form, in whole or in part, without
-/ the prior written consent of Tensilica Inc.
-*/
-
-/* xtav200.h - Xtensa Avnet LX200 (XT-AV200) board specific definitions */
-
-#ifndef _INC_XTAV200_H_
-#define _INC_XTAV200_H_
-
-#include
-#include
-
-#define XTBOARD_NAME "XT-AV200"
-
-
-/*
- * Default assignment of XTAV200 devices to external interrupts.
- */
-
-/* Ethernet interrupt: */
-#ifdef XCHAL_EXTINT1_NUM
-#define ETHERNET_INTNUM XCHAL_EXTINT1_NUM
-#define ETHERNET_INTLEVEL XCHAL_EXTINT1_LEVEL
-#define ETHERNET_INTMASK XCHAL_EXTINT1_MASK
-#else
-#define ETHERNET_INTMASK 0
-#endif
-
-/* UART interrupt: */
-#ifdef XCHAL_EXTINT0_NUM
-#define UART16550_INTNUM XCHAL_EXTINT0_NUM
-#define UART16550_INTLEVEL XCHAL_EXTINT0_LEVEL
-#define UART16550_INTMASK XCHAL_EXTINT0_MASK
-#else
-#define UART16550_INTMASK 0
-#endif
-
-/* Audio output interrupt (I2S FIFO underrun): */
-#ifdef XCHAL_EXTINT2_NUM
-#define AUDIO_INTNUM XCHAL_EXTINT2_NUM
-#define AUDIO_INTLEVEL XCHAL_EXTINT2_LEVEL
-#define AUDIO_INTMASK XCHAL_EXTINT2_MASK
-#else
-#define AUDIO_INTMASK 0
-#endif
-
-/* Audio output (I2S FIFO level) interrupt: */
-#ifdef XCHAL_EXTINT3_NUM
-#define AUDIO_I2SLVL_INTNUM XCHAL_EXTINT3_NUM
-#define AUDIO_I2SLVL_INTLEVEL XCHAL_EXTINT3_LEVEL
-#define AUDIO_I2SLVL_INTMASK XCHAL_EXTINT3_MASK
-#else
-#define AUDIO_I2SLVL_INTMASK 0
-#endif
-
-/* Audio input (ADC FIFO level) interrupt: */
-#ifdef XCHAL_EXTINT4_NUM
-#define AUDIO_ADCLVL_INTNUM XCHAL_EXTINT4_NUM
-#define AUDIO_ADCLVL_INTLEVEL XCHAL_EXTINT4_LEVEL
-#define AUDIO_ADCLVL_INTMASK XCHAL_EXTINT4_MASK
-#else
-#define AUDIO_ADCLVL_INTMASK 0
-#endif
-
-
-/*
- * Device addresses.
- *
- * Note: for endianness-independence, use 32-bit loads and stores for all
- * register accesses to Ethernet, UART and LED devices. Undefined bits
- * may need to be masked out if needed when reading if the actual register
- * size is smaller than 32 bits.
- *
- * Note: XTAV200 bus byte lanes are defined in terms of msbyte and lsbyte
- * relative to the processor. So 32-bit registers are accessed consistently
- * from both big and little endian processors. However, this means byte
- * sequences are not consistent between big and little endian processors.
- * This is fine for RAM, and for ROM if ROM is created for a specific
- * processor (and thus has correct byte sequences). However this may be
- * unexpected for Flash, which might contain a file-system that one wants
- * to use for multiple processor configurations (eg. the Flash might contain
- * the Ethernet card's address, endianness-independent application data, etc).
- * That is, byte sequences written in Flash by a core of a given endianness
- * will be byte-swapped when seen by a core of the other endianness.
- * Someone implementing an endianness-independent Flash file system will
- * likely handle this byte-swapping issue in the Flash driver software.
- */
-
-#define XTBOARD_FLASH_MAXSIZE 0x1000000 /* 16 MB */
-
-#ifdef XSHAL_IOBLOCK_BYPASS_PADDR
-
-/* Flash Memory: */
-# define XTBOARD_FLASH_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x08000000)
-
-/* FPGA registers: */
-# define XTBOARD_FPGAREGS_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D020000)
-
-/* Ethernet controller/transceiver SONIC SN83934: */
-# define ETHERNET_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D030000)
-
-/* UART National-Semi PC16550D: */
-# define UART16550_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D050000)
-
-/* TI 320AIC23/28-TSSOP Stereo Audio Codec: */
-# define AUDIO_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D070000)
-
-/* Boot 128K Sram address: */
-# define BOOT_SRAM_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D400000)
-
-/* Ethernet buffer: */
-# define ETHERNET_BUFFER_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D800000)
-
-#endif /* XSHAL_IOBLOCK_BYPASS_PADDR */
-
-/* These devices might be accessed cached: */
-#ifdef XSHAL_IOBLOCK_CACHED_PADDR
-# define XTBOARD_FLASH_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0x08000000)
-# define ETHERNET_BUFFER_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0x0D800000)
-# define BOOT_SRAM_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0x0D400000)
-#endif /* XSHAL_IOBLOCK_CACHED_PADDR */
-
-
-/*** Same thing over again, this time with virtual addresses: ***/
-
-#ifdef XSHAL_IOBLOCK_BYPASS_VADDR
-
-/* Flash Memory: */
-# define XTBOARD_FLASH_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x08000000)
-
-/* FPGA registers: */
-# define XTBOARD_FPGAREGS_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D020000)
-
-/* Ethernet controller/transceiver SONIC SN83934: */
-# define ETHERNET_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D030000)
-
-/* UART National-Semi PC16550D: */
-# define UART16550_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D050000)
-
-/* TI 320AIC23/28-TSSOP Stereo Audio Codec: */
-# define AUDIO_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D070000)
-
-/* 128K Sram address: */
-# define BOOT_SRAM_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D400000)
-
-/* Ethernet buffer: */
-# define ETHERNET_BUFFER_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D800000)
-
-#endif /* XSHAL_IOBLOCK_BYPASS_VADDR */
-
-/* These devices might be accessed cached: */
-#ifdef XSHAL_IOBLOCK_CACHED_VADDR
-# define XTBOARD_FLASH_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0x08000000)
-# define AUDIO_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0x0D070000)
-# define ETHERNET_BUFFER_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0x0D800000)
-# define BOOT_SRAM_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0x0D400000)
-#endif /* XSHAL_IOBLOCK_CACHED_VADDR */
-
-
-/* System ROM: */
-#define XTBOARD_ROM_SIZE XSHAL_ROM_SIZE
-#ifdef XSHAL_ROM_VADDR
-#define XTBOARD_ROM_VADDR XSHAL_ROM_VADDR
-#endif
-#ifdef XSHAL_ROM_PADDR
-#define XTBOARD_ROM_PADDR XSHAL_ROM_PADDR
-#endif
-
-/* System RAM: */
-#define XTBOARD_RAM_SIZE XSHAL_RAM_SIZE
-#ifdef XSHAL_RAM_VADDR
-#define XTBOARD_RAM_VADDR XSHAL_RAM_VADDR
-#endif
-#ifdef XSHAL_RAM_PADDR
-#define XTBOARD_RAM_PADDR XSHAL_RAM_PADDR
-#endif
-#define XTBOARD_RAM_BYPASS_VADDR XSHAL_RAM_BYPASS_VADDR
-#define XTBOARD_RAM_BYPASS_PADDR XSHAL_RAM_BYPASS_PADDR
-
-
-
-/*
- * Things that depend on device addresses.
- */
-
-
-#define XTBOARD_CACHEATTR_WRITEBACK XSHAL_XT2000_CACHEATTR_WRITEBACK
-#define XTBOARD_CACHEATTR_WRITEALLOC XSHAL_XT2000_CACHEATTR_WRITEALLOC
-#define XTBOARD_CACHEATTR_WRITETHRU XSHAL_XT2000_CACHEATTR_WRITETHRU
-#define XTBOARD_CACHEATTR_BYPASS XSHAL_XT2000_CACHEATTR_BYPASS
-#define XTBOARD_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_DEFAULT
-
-#define XTBOARD_BUSINT_PIPE_REGIONS XSHAL_XT2000_PIPE_REGIONS
-#define XTBOARD_BUSINT_SDRAM_REGIONS XSHAL_XT2000_SDRAM_REGIONS
-
-
-/*
- * FPGA registers.
- * All these registers are normally accessed using 32-bit loads/stores.
- */
-
-/* Register offsets: */
-#define XTBOARD_DATECD_OFS 0x00 /* date code (read-only) */
-#define XTBOARD_CLKFRQ_OFS 0x04 /* clock frequency Hz (read-only) */
-#define XTBOARD_SYSLED_OFS 0x08 /* LEDs */
-#define XTBOARD_DIPSW_OFS 0x0C /* DIP switch bits (read-only) */
-#define XTBOARD_SWRST_OFS 0x10 /* software reset */
-
-/* Physical register addresses: */
-#ifdef XTBOARD_FPGAREGS_PADDR
-#define XTBOARD_DATECD_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_DATECD_OFS)
-#define XTBOARD_CLKFRQ_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_CLKFRQ_OFS)
-#define XTBOARD_SYSLED_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_SYSLED_OFS)
-#define XTBOARD_DIPSW_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_DIPSW_OFS)
-#define XTBOARD_SWRST_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_SWRST_OFS)
-#endif
-
-/* Virtual register addresses: */
-#ifdef XTBOARD_FPGAREGS_VADDR
-#define XTBOARD_DATECD_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_DATECD_OFS)
-#define XTBOARD_CLKFRQ_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_CLKFRQ_OFS)
-#define XTBOARD_SYSLED_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_SYSLED_OFS)
-#define XTBOARD_DIPSW_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_DIPSW_OFS)
-#define XTBOARD_SWRST_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_SWRST_OFS)
-/* Register access (for C code): */
-#define XTBOARD_DATECD_REG (*(volatile unsigned*) XTBOARD_DATECD_VADDR)
-#define XTBOARD_CLKFRQ_REG (*(volatile unsigned*) XTBOARD_CLKFRQ_VADDR)
-#define XTBOARD_SYSLED_REG (*(volatile unsigned*) XTBOARD_SYSLED_VADDR)
-#define XTBOARD_DIPSW_REG (*(volatile unsigned*) XTBOARD_DIPSW_VADDR)
-#define XTBOARD_SWRST_REG (*(volatile unsigned*) XTBOARD_SWRST_VADDR)
-#endif
-
-/* DATECD (date code; when core was built) bit fields: */
-/* BCD-coded month (01..12): */
-#define XTBOARD_DATECD_MONTH_SHIFT 24
-#define XTBOARD_DATECD_MONTH_BITS 8
-#define XTBOARD_DATECD_MONTH_MASK 0xFF000000
-/* BCD-coded day (01..31): */
-#define XTBOARD_DATECD_DAY_SHIFT 16
-#define XTBOARD_DATECD_DAY_BITS 8
-#define XTBOARD_DATECD_DAY_MASK 0x00FF0000
-/* BCD-coded year (2001..9999): */
-#define XTBOARD_DATECD_YEAR_SHIFT 0
-#define XTBOARD_DATECD_YEAR_BITS 16
-#define XTBOARD_DATECD_YEAR_MASK 0x0000FFFF
-
-/* SYSLED (system LED) bit fields: */
-
-/* LED control bits (off=0, on=1): */
-#define XTBOARD_SYSLED_USER_SHIFT 0
-#define XTBOARD_SYSLED_USER_BITS 4
-#define XTBOARD_SYSLED_USER_MASK 0x0000000F
-
-/* DIP Switch (left=sw1=lsb=bit0, right=sw8=msb=bit7; off=0, on=1): */
-/* DIP switch bit fields (bit6/sw7 is reserved and presently unused): */
-#define XTBOARD_DIPSW_USER_SHIFT 0 /* labeled 1-6 (1=lsb) */
-#define XTBOARD_DIPSW_USER_BITS 6
-#define XTBOARD_DIPSW_USER_MASK 0x0000003F
-#define XTBOARD_DIPSW_BOOT_SHIFT 7 /* labeled 8 (msb) */
-#define XTBOARD_DIPSW_BOOT_BITS 1
-#define XTBOARD_DIPSW_BOOT_MASK 0x00000080
-/* Boot settings: bit7/sw8, off=0, on=1 (this switch controls hardware): */
-#define XTBOARD_DIPSW_BOOT_RAM (0<
-
diff --git a/components/esp32/include/xtensa/xtav60.h b/components/esp32/include/xtensa/xtav60.h
deleted file mode 100644
index d7c8e3aed8..0000000000
--- a/components/esp32/include/xtensa/xtav60.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/* Copyright (c) 2002-2013 by Tensilica Inc. ALL RIGHTS RESERVED.
-/ These coded instructions, statements, and computer programs are the
-/ copyrighted works and confidential proprietary information of Tensilica Inc.
-/ They may not be modified, copied, reproduced, distributed, or disclosed to
-/ third parties in any manner, medium, or form, in whole or in part, without
-/ the prior written consent of Tensilica Inc.
-*/
-
-/* xtav60.h - Xtensa Avnet LX60 (XT-AV60) board specific definitions */
-
-#ifndef _INC_XTAV60_H_
-#define _INC_XTAV60_H_
-
-#include
-#include
-
-#define XTBOARD_NAME "XT-AV60"
-
-
-/*
- * Default assignment of XTAV60 devices to external interrupts.
- */
-
-/* Ethernet interrupt: */
-#ifdef XCHAL_EXTINT1_NUM
-#define ETHERNET_INTNUM XCHAL_EXTINT1_NUM
-#define ETHERNET_INTLEVEL XCHAL_EXTINT1_LEVEL
-#define ETHERNET_INTMASK XCHAL_EXTINT1_MASK
-#else
-#define ETHERNET_INTMASK 0
-#endif
-
-/* UART interrupt: */
-#ifdef XCHAL_EXTINT0_NUM
-#define UART16550_INTNUM XCHAL_EXTINT0_NUM
-#define UART16550_INTLEVEL XCHAL_EXTINT0_LEVEL
-#define UART16550_INTMASK XCHAL_EXTINT0_MASK
-#else
-#define UART16550_INTMASK 0
-#endif
-
-/*
- * Device addresses.
- *
- * Note: for endianness-independence, use 32-bit loads and stores for all
- * register accesses to Ethernet, UART and LED devices. Undefined bits
- * may need to be masked out if needed when reading if the actual register
- * size is smaller than 32 bits.
- *
- * Note: XTAV60 bus byte lanes are defined in terms of msbyte and lsbyte
- * relative to the processor. So 32-bit registers are accessed consistently
- * from both big and little endian processors. However, this means byte
- * sequences are not consistent between big and little endian processors.
- * This is fine for RAM, and for ROM if ROM is created for a specific
- * processor (and thus has correct byte sequences). However this may be
- * unexpected for Flash, which might contain a file-system that one wants
- * to use for multiple processor configurations (eg. the Flash might contain
- * the Ethernet card's address, endianness-independent application data, etc).
- * That is, byte sequences written in Flash by a core of a given endianness
- * will be byte-swapped when seen by a core of the other endianness.
- * Someone implementing an endianness-independent Flash file system will
- * likely handle this byte-swapping issue in the Flash driver software.
- */
-
-#define XTBOARD_FLASH_MAXSIZE 0x400000 /* 4 MB */
-
-#ifdef XSHAL_IOBLOCK_BYPASS_PADDR
-
-/* Flash Memory: */
-# define XTBOARD_FLASH_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x08000000)
-
-/* FPGA registers: */
-# define XTBOARD_FPGAREGS_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D020000)
-
-/* Ethernet controller/transceiver SONIC SN83934: */
-# define ETHERNET_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D030000)
-# define ETHERNET_CONTROLLER_PADDR ETHERNET_PADDR /* legacy macro */
-
-/* Display controller Sunplus SPLC780D, LCD Display MYTech MOC-16216B-B: */
-# define SPLC780D_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D040000)
-
-/* UART National-Semi PC16550D: */
-# define UART16550_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D050000)
-
-/* Boot 128K Sram address: */
-# define BOOT_SRAM_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D400000)
-
-/* Ethernet buffer: */
-# define ETHERNET_BUFFER_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D800000)
-
-#endif /* XSHAL_IOBLOCK_BYPASS_PADDR */
-
-/* These devices might be accessed cached: */
-#ifdef XSHAL_IOBLOCK_CACHED_PADDR
-# define XTBOARD_FLASH_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0x08000000)
-# define ETHERNET_BUFFER_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0x0D800000)
-# define BOOT_SRAM_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0x0D400000)
-#endif /* XSHAL_IOBLOCK_CACHED_PADDR */
-
-
-/*** Same thing over again, this time with virtual addresses: ***/
-
-#ifdef XSHAL_IOBLOCK_BYPASS_VADDR
-
-/* Flash Memory: */
-# define XTBOARD_FLASH_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x08000000)
-
-/* FPGA registers: */
-# define XTBOARD_FPGAREGS_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D020000)
-
-/* Ethernet controller/transceiver SONIC SN83934: */
-# define ETHERNET_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D030000)
-
-/* Display controller Sunplus SPLC780D, LCD Display MYTech MOC-16216B-B: */
-# define SPLC780D_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D040000)
-
-/* UART National-Semi PC16550D: */
-# define UART16550_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D050000)
-
-/* 128K Sram address: */
-# define BOOT_SRAM_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D400000)
-
-/* Ethernet buffer: */
-# define ETHERNET_BUFFER_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D800000)
-
-#endif /* XSHAL_IOBLOCK_BYPASS_VADDR */
-
-/* These devices might be accessed cached: */
-#ifdef XSHAL_IOBLOCK_CACHED_VADDR
-# define XTBOARD_FLASH_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0x08000000)
-# define ETHERNET_BUFFER_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0x0D800000)
-# define BOOT_SRAM_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0x0D400000)
-#endif /* XSHAL_IOBLOCK_CACHED_VADDR */
-
-
-/* System ROM: */
-#define XTBOARD_ROM_SIZE XSHAL_ROM_SIZE
-#ifdef XSHAL_ROM_VADDR
-#define XTBOARD_ROM_VADDR XSHAL_ROM_VADDR
-#endif
-#ifdef XSHAL_ROM_PADDR
-#define XTBOARD_ROM_PADDR XSHAL_ROM_PADDR
-#endif
-
-/* System RAM: */
-#define XTBOARD_RAM_SIZE XSHAL_RAM_SIZE
-#ifdef XSHAL_RAM_VADDR
-#define XTBOARD_RAM_VADDR XSHAL_RAM_VADDR
-#endif
-#ifdef XSHAL_RAM_PADDR
-#define XTBOARD_RAM_PADDR XSHAL_RAM_PADDR
-#endif
-#define XTBOARD_RAM_BYPASS_VADDR XSHAL_RAM_BYPASS_VADDR
-#define XTBOARD_RAM_BYPASS_PADDR XSHAL_RAM_BYPASS_PADDR
-
-
-
-/*
- * Things that depend on device addresses.
- */
-
-
-#define XTBOARD_CACHEATTR_WRITEBACK XSHAL_XT2000_CACHEATTR_WRITEBACK
-#define XTBOARD_CACHEATTR_WRITEALLOC XSHAL_XT2000_CACHEATTR_WRITEALLOC
-#define XTBOARD_CACHEATTR_WRITETHRU XSHAL_XT2000_CACHEATTR_WRITETHRU
-#define XTBOARD_CACHEATTR_BYPASS XSHAL_XT2000_CACHEATTR_BYPASS
-#define XTBOARD_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_DEFAULT
-
-#define XTBOARD_BUSINT_PIPE_REGIONS XSHAL_XT2000_PIPE_REGIONS
-#define XTBOARD_BUSINT_SDRAM_REGIONS XSHAL_XT2000_SDRAM_REGIONS
-
-
-/*
- * FPGA registers.
- * All these registers are normally accessed using 32-bit loads/stores.
- */
-
-/* Register offsets: */
-#define XTBOARD_DATECD_OFS 0x00 /* date code (read-only) */
-#define XTBOARD_CLKFRQ_OFS 0x04 /* clock frequency Hz (read-only) */
-#define XTBOARD_DIPSW_OFS 0x0C /* DIP switch bits (read-only) */
-#define XTBOARD_SWRST_OFS 0x10 /* software reset */
-
-/* Physical register addresses: */
-#ifdef XTBOARD_FPGAREGS_PADDR
-#define XTBOARD_DATECD_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_DATECD_OFS)
-#define XTBOARD_CLKFRQ_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_CLKFRQ_OFS)
-#define XTBOARD_DIPSW_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_DIPSW_OFS)
-#define XTBOARD_SWRST_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_SWRST_OFS)
-#endif
-
-/* Virtual register addresses: */
-#ifdef XTBOARD_FPGAREGS_VADDR
-#define XTBOARD_DATECD_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_DATECD_OFS)
-#define XTBOARD_CLKFRQ_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_CLKFRQ_OFS)
-#define XTBOARD_DIPSW_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_DIPSW_OFS)
-#define XTBOARD_SWRST_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_SWRST_OFS)
-/* Register access (for C code): */
-#define XTBOARD_DATECD_REG (*(volatile unsigned*) XTBOARD_DATECD_VADDR)
-#define XTBOARD_CLKFRQ_REG (*(volatile unsigned*) XTBOARD_CLKFRQ_VADDR)
-#define XTBOARD_DIPSW_REG (*(volatile unsigned*) XTBOARD_DIPSW_VADDR)
-#define XTBOARD_SWRST_REG (*(volatile unsigned*) XTBOARD_SWRST_VADDR)
-#endif
-
-/* DATECD (date code; when core was built) bit fields: */
-/* BCD-coded month (01..12): */
-#define XTBOARD_DATECD_MONTH_SHIFT 24
-#define XTBOARD_DATECD_MONTH_BITS 8
-#define XTBOARD_DATECD_MONTH_MASK 0xFF000000
-/* BCD-coded day (01..31): */
-#define XTBOARD_DATECD_DAY_SHIFT 16
-#define XTBOARD_DATECD_DAY_BITS 8
-#define XTBOARD_DATECD_DAY_MASK 0x00FF0000
-/* BCD-coded year (2001..9999): */
-#define XTBOARD_DATECD_YEAR_SHIFT 0
-#define XTBOARD_DATECD_YEAR_BITS 16
-#define XTBOARD_DATECD_YEAR_MASK 0x0000FFFF
-
-/* DIP Switch (left=sw1=lsb=bit0, right=sw8=msb=bit7; off=0, on=1): */
-/* DIP switch bit fields (bit6/sw7 is reserved and presently unused): */
-#define XTBOARD_DIPSW_USER_SHIFT 0 /* labeled 1-6 (1=lsb) */
-#define XTBOARD_DIPSW_USER_BITS 6
-#define XTBOARD_DIPSW_USER_MASK 0x0000003F
-#define XTBOARD_DIPSW_BOOT_SHIFT 7 /* labeled 8 (msb) */
-#define XTBOARD_DIPSW_BOOT_BITS 1
-#define XTBOARD_DIPSW_BOOT_MASK 0x00000080
-/* Boot settings: bit7/sw8, off=0, on=1 (this switch controls hardware): */
-#define XTBOARD_DIPSW_BOOT_RAM (0<
-
diff --git a/components/esp32/include/xtensa/xtav60/xtensa/lcd-splc780d-board.h b/components/esp32/include/xtensa/xtav60/xtensa/lcd-splc780d-board.h
deleted file mode 100644
index 629a32581a..0000000000
--- a/components/esp32/include/xtensa/xtav60/xtensa/lcd-splc780d-board.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
-
-Copyright (c) 2006-2007 by Tensilica Inc. ALL RIGHTS RESERVED.
-These coded instructions, statements, and computer programs are the
-copyrighted works and confidential proprietary information of Tensilica Inc.
-They may not be modified, copied, reproduced, distributed, or disclosed to
-third parties in any manner, medium, or form, in whole or in part, without
-the prior written consent of Tensilica Inc.
---------------------------------------------------------------------------------
-
-lcd-splc780d-board.h Board-specific LCD info on Avnet AV60 (XT-AV60) board.
-
-Interface between board-independent driver and board-specific header.
-
-This is used by a board-independent SPLC780D LCD controller driver to obtain
-board-specific information about LCD displays on the board, such as the
-controller register base address and spacing (a function of how the address
-lines are connected on the board) and length of the visible window of the
-display (a function of the LCD panel the controller drives). The driver does
-not refer directly to the board-specific header, which therefore is not
-constrained to use macro names consistent with other boards.
-
-!! Must not contain any board-specific macro names (only controller specific) !!
-
-Included at compile-time via an include path specific to the board.
-
-The XT-AV60 board contains a single MYTech MOC-16216B-B display driven by
-a Sunplus SPLC870D controller.
-
-*******************************************************************************/
-
-#ifndef _LCD_SPLC780D_BOARD_H
-#define _LCD_SPLC780D_BOARD_H
-
-#include /* Board info */
-
-
-/* Base address of the controller's registers. */
-#ifdef SPLC780D_VADDR
-#define SPLC780D_REGBASE SPLC780D_VADDR
-#endif
-
-/*
-The controller's registers are connected at word addresses on the XT-AV60.
-Each byte-wide register appears as the least-significant-byte (LSB) of the
-word regardless of the endianness of the processor (so if using word accesses
-then endianness doesn't matter).
-*/
-#define SPLC780D_REGSPACING 4
-typedef unsigned splc780d_reg_t;
-
-/* Include generic information shared by all boards that use this device. */
-#include
-
-
-/* Display limits of the LCD panel. */
-#define DISPLAY_VISIBLE_LEN 16 /* length (chars) of visible window */
-
-#endif /* _LCD_SPLC780D_BOARD_H */
-
diff --git a/components/esp32/include/xtensa/xtbsp.h b/components/esp32/include/xtensa/xtbsp.h
deleted file mode 100644
index 62356dd868..0000000000
--- a/components/esp32/include/xtensa/xtbsp.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/*******************************************************************************
-
- Copyright (c) 2006-2009 Tensilica Inc.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
---------------------------------------------------------------------------------
-
-xtbsp.h Xtensa Board Support Package API
-
-This API defines a minimal set of board-support functions that every supported
-Xtensa board is expected to provide in the board-support-package (BSP) library
-associated with the board-specific LSP. Only basic board functions are provided
-in this board-independent API. API functions not applicable to a board must be
-stubbed in its BSP library. More complex operations must use a board-specific
-interface. Functions are grouped by type of peripheral device.
-
-*******************************************************************************/
-
-#ifndef _XTBSP_H_
-#define _XTBSP_H_
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*******************************************************************************
-BOARD INITIALIZATION.
-The board with all its devices is initialized by xtbsp_board_init().
-Individual devices represented by this API can be reinitialized at any
-time by calling their inidividual device init functions (grouped with
-other device functions). This might be useful to (say) change the baud
-rate of the UART.
-*/
-
-
-/*
-Initialize the board. Must call before any other API function.
-Iniitializes BSP, board in general, and all devices on the board.
-*/
-extern void xtbsp_board_init(void);
-
-
-/*******************************************************************************
-BOARD CHARACTERISTICS and CONVENIENCE FUNCTIONS.
-Board support functions not associated with a particular peripheral device.
-*/
-
-/*
-Return a short string representing the type of board.
-If the board has a display, the string must fit on a single line.
-*/
-extern const char * xtbsp_board_name(void);
-
-/*
-Hardware reset the entire board (if possible). Does not return if successful.
-If this function returns, it is stubbed out or not possible with this board.
-*/
-extern void xtbsp_board_reset(void);
-
-/*
-Return the clock frequency in Hertz. May be constant or computed.
-*/
-extern unsigned xtbsp_clock_freq_hz(void);
-
-/*
-Return the clock period in picoseconds. May be constant or computed.
-*/
-extern unsigned xtbsp_clock_period_ps(void);
-
-/*
-Spin (at least) a number of cycles per the processor's CCOUNT register.
-Unlike a s/w delay loop, the duration is not affected by compiler
-optimization or interrupts completed within the delay period.
-If the processor doesn't have CCOUNT, a s/w delay loop is used to obtain
-a rough approximation of the cycle count.
-*/
-extern void xtbsp_delay_cycles(unsigned cycles);
-
-/*
-Spin at least a number of nanoseconds (approximate and err in the high side).
-BSP implementation should do this efficiently, avoiding integer overflow or
-excessive loss of precision, run-time division or floating point.
-Function implementation (vs. macro) allows BSP to optimize for the clock
-frequency by pre-computing (or using constant) scale factors.
-*/
-extern void xtbsp_delay_ns(unsigned ns);
-
-
-/*******************************************************************************
-C LIBRARY SUPPORT.
-These functions are called by the C library libgloss interface.
-Their names are predetermined apart from this BSP API.
-*/
-
-/*
-Initialize the board. Called by C library initialization code.
-Usually simply calls xtbsp_board_init().
-*/
-extern void board_init(void);
-
-/*
-(Wait for and) Input a single byte from the default character I/O
-device. Return -1 if there is no input device.
-This device is usually a UART and this function calls xtbsp_uart_getchar().
-On some boards (eg.) it might be a directly connected keyboard.
-*/
-extern int inbyte(void);
-
-/*
-Output a single char to the default character I/O device (and wait
-until it's been taken).
-This device is usually a UART and this function calls xtbsp_uart_putchar().
-On some boards (eg.) it might be a directly connected bit-mapped screen.
-*/
-extern void outbyte(int c);
-
-
-/*******************************************************************************
-UART (SERIAL I/O).
-Supports a single UART in a simple polling mode and provides control of
-receiver and transmitter data interrupts (client must provide handler).
-Provides a mapping to processor interrupt number which can be used with
-the HAL to control processor interrupt enable (INTENABLE) etc.
-*/
-
-/* Bitmasks to identify UART interrupts. */
-typedef enum xtbsp_uart_int {
- xtbsp_uart_int_rx = 1<<0,
- xtbsp_uart_int_tx = 1<<1,
- /* mask of all valid interrupt bits */
- xtbsp_uart_int_all = (1<<2)-1
-} xtbsp_uart_int;
-
-/*
-Return non-zero if the board has a UART.
-*/
-extern int xtbsp_uart_exists(void);
-
-/*
-Initialize the UART:
- parity = 0 (none), 1 (odd), or 2 (even).
- nstop = 1 or 2 (stop bits).
- ndata = 7 or 8 (data bits).
-Disables all UART interrupts.
-Returns non-zero if failed (perhaps due to unsupported parameter values).
-Must call before any of the following functions.
-*/
-extern int xtbsp_uart_init(unsigned baud, unsigned ndata,
- unsigned parity, unsigned nstop);
-#define xtbsp_uart_init_default() xtbsp_uart_init(38400, 8, 0, 1)
-
-/*
-(Wait for and) Input a single char from the UART.
-Any pending xtbsp_uart_int_rx interrupt is cleared.
-*/
-extern char xtbsp_uart_getchar(void);
-
-/*
-(Wait for transmitter ready and) Output a single char to the UART.
-Any pending xtbsp_uart_int_tx interrupt is cleared.
-*/
-extern void xtbsp_uart_putchar(const char c);
-
-/*
-Return true (non-zero) if a character has been received and is ready
-to be input by xtbsp_uart_getchar() without waiting, else return 0.
-*/
-extern int xtbsp_uart_get_isready(void);
-
-/*
-Return non-zero if a character may be output by xtbsp_uart_putchar()
-without waiting, else return 0.
-Any pending xtbsp_uart_int_tx interrupt is cleared.
-*/
-extern int xtbsp_uart_put_isready(void);
-
-/*
-Return the enable status of all UART interrupts represented by this API,
-that is those with bits defined in type xtbsp_uart_int (1 bit = enabled).
-This is the enable status at the device, not the processor's INTENABLE.
-*/
-extern xtbsp_uart_int xtbsp_uart_int_enable_status(void);
-
-/*
-Enable selected UART interrupts at the device.
-*/
-extern void xtbsp_uart_int_enable(const xtbsp_uart_int mask);
-
-/*
-Disable selected UART interrupts at the device.
-*/
-extern void xtbsp_uart_int_disable(const xtbsp_uart_int mask);
-
-/*
-Return the interrupt number (0..31) to which the selected UART interrupt
-is connected. May be used with the link-time HAL to obtain more information,
-eg. Xthal_intlevel_mask[xtbsp_uart_int_number(xtbsp_uart_int_rx)]
-This information can be used to control the processor's INTENABLE, etc.
-Result is -1 if not connected, undefined if mask has more than 1 bit set.
-*/
-extern int xtbsp_uart_int_number(const xtbsp_uart_int mask);
-
-
-/*******************************************************************************
-DISPLAY.
-Supports a single display that can render a series of ASCII characters.
-Functions are provided to perform generic display tasks such as display
-a string, display character by character, or blank the display.
-Chars are 7-bit printable ASCII. Strings are C style NUL \0 terminated.
-These functions busy-wait for any required timing delays so the caller does
-not have to deal with timing. Some displays require long delays which in
-some client applications warrant a board and RTOS specific approach to
-driving the display, however that is beyond the scope of this API.
-*/
-
-/*
-Return non-zero if board has a display.
-*/
-extern int xtbsp_display_exists(void);
-
-/*
-Initialize the display. Must call before any of the following functions.
-*/
-extern void xtbsp_display_init(void);
-
-/*
-Display a single char at position pos (0 is leftmost). Other positions are
-left untouched. Positions beyond the width of the display are ignored.
-*/
-extern void xtbsp_display_char(unsigned pos, const char c);
-
-/*
-Display a string. Blank-pad to or truncate at the end of the display
-(overwrites any previous string so don't need to blank display first).
-*/
-extern void xtbsp_display_string(const char *s);
-
-/*
-Blank (clear) the entire display.
-*/
-extern void xtbsp_display_blank(void);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _XTBSP_H_ */
diff --git a/components/esp32/include/xtensa/xtkc705.h b/components/esp32/include/xtensa/xtkc705.h
deleted file mode 100644
index 831c15d541..0000000000
--- a/components/esp32/include/xtensa/xtkc705.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Copyright (c) 2006-2013 by Tensilica Inc. ALL RIGHTS RESERVED.
-/ These coded instructions, statements, and computer programs are the
-/ copyrighted works and confidential proprietary information of Tensilica Inc.
-/ They may not be modified, copied, reproduced, distributed, or disclosed to
-/ third parties in any manner, medium, or form, in whole or in part, without
-/ the prior written consent of Tensilica Inc.
-*/
-
-/* xtkc705.h - Xtensa Xilinx KC705 (XT-KC705) board specific definitions */
-
-/* 99.9% same as ML605, just indicate we're KC705 and include ML605 header: */
-#define XTBOARD_IS_KC705 1
-#include
-
diff --git a/components/esp32/include/xtensa/xtkc705/xtensa/board.h b/components/esp32/include/xtensa/xtkc705/xtensa/board.h
deleted file mode 100644
index 5d2d834802..0000000000
--- a/components/esp32/include/xtensa/xtkc705/xtensa/board.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * board.h - Include board-specific definitions
- *
- * Copyright (c) 2013 by Tensilica Inc. ALL RIGHTS RESERVED.
- * These coded instructions, statements, and computer programs are the
- * copyrighted works and confidential proprietary information of Tensilica Inc.
- * They may not be modified, copied, reproduced, distributed, or disclosed to
- * third parties in any manner, medium, or form, in whole or in part, without
- * the prior written consent of Tensilica Inc.
- */
-
-#include
-
diff --git a/components/esp32/include/xtensa/xtload-api.h b/components/esp32/include/xtensa/xtload-api.h
deleted file mode 100644
index 4e2297f510..0000000000
--- a/components/esp32/include/xtensa/xtload-api.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Customer ID=11656; Build=0x5f626; Copyright (c) 2003-2012 Tensilica Inc. ALL RIGHTS RESERVED.
- These coded instructions, statements, and computer programs are the
- copyrighted works and confidential proprietary information of Tensilica Inc.
- They may not be modified, copied, reproduced, distributed, or disclosed to
- third parties in any manner, medium, or form, in whole or in part, without
- the prior written consent of Tensilica Inc. */
-
-#ifndef _XTLOAD_API_H
-#define _XTLOAD_API_H
-
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define XTENSA_BYTES_PER_WORD 4
-#define XLOAD_ALL_CORES -1
-
-typedef int core_number_t;
-typedef uint32_t xtload_address_t;
-typedef uint32_t xtload_word_count_t;
-typedef uint32_t * xtload_word_ptr_t;
-
-/* These functions correspond one-to-one with xt-load script
- commands. See the documentation for xt-load for their usage.
-
- There are however, several higher-level script commands--such as
- load-elf-file--which don't have direct analogues here. These
- "missing" commands are essentially just macros that result in
- several of these commands below. Note that you can execute several
- of these commands, then the results of a script, or vice-versa.
- */
-
-void xtload_bootloader_wake (void);
-void xtload_bootloader_sleep (void);
-void xtload_bootloader_done (void);
-void xtload_bootloader_not_done (void);
-void xtload_reset_and_cont (core_number_t core);
-void xtload_stall_and_reset (core_number_t core);
-#define xtload_reset_and_stall xtload_stall_and_reset
-void xtload_stall_and_target (core_number_t core);
-void xtload_ignore_and_stall (core_number_t core);
-void xtload_ignore_and_cont (core_number_t core);
-#define xtload_ignore_and_continue xtload_ignore_and_cont
-void xtload_read_words (xtload_address_t addr, xtload_word_count_t count);
-void xtload_zero_words (xtload_address_t addr, xtload_word_count_t count);
-void xtload_write_words (int swap, xtload_address_t addr,
- xtload_word_ptr_t ptr, xtload_word_count_t count);
-void xtload_setup_write_words (xtload_address_t addr, xtload_word_count_t count);
-void xtload_read_register (core_number_t core);
-
-/* *I M P O R T A N T*
-
- The bootloader API calls this function whenever it outputs a word
- to the bootloader hardware chain.
-
- Because the API has no information about how the bootloader
- hardware is connected to the host hardware, the user must
- implement this function to write a word to the bootloader's register.
-
- A user's implementation might write the bytes to an Xtensa queue or
- to a memory-mapped register.
-
- For example, xt-load uses this API just like any other client. Its
- implementation of this function simply writes this word to an
- output file.
-*/
-
-void xtload_user_output_word (uint32_t word);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _XTLOAD_API_H */
-
diff --git a/components/esp32/include/xtensa/xtml605.h b/components/esp32/include/xtensa/xtml605.h
deleted file mode 100644
index 5f54d700d1..0000000000
--- a/components/esp32/include/xtensa/xtml605.h
+++ /dev/null
@@ -1,338 +0,0 @@
-/* Copyright (c) 2007-2013 by Tensilica Inc. ALL RIGHTS RESERVED.
-/ These coded instructions, statements, and computer programs are the
-/ copyrighted works and confidential proprietary information of Tensilica Inc.
-/ They may not be modified, copied, reproduced, distributed, or disclosed to
-/ third parties in any manner, medium, or form, in whole or in part, without
-/ the prior written consent of Tensilica Inc.
-*/
-
-/* xtml605.h - Xtensa Xilinx ML605 (XT-ML605) board specific definitions */
-/* xtkc705.h - Also includes this, for the Xilinx KC705 (XT-KC705). */
-
-#ifndef _INC_ML605_H_
-#define _INC_ML605_H_
-
-#include
-#include
-
-#if XTBOARD_IS_KC705
-#define XTBOARD_NAME "XT-KC705"
-#else
-#define XTBOARD_NAME "XT-ML605"
-#endif
-
-
-/*
- * Default assignment of ML605 devices to external interrupts.
- */
-
-/* Ethernet interrupt: */
-#ifdef XCHAL_EXTINT1_NUM
-#define ETHERNET_INTNUM XCHAL_EXTINT1_NUM
-#define ETHERNET_INTLEVEL XCHAL_EXTINT1_LEVEL
-#define ETHERNET_INTMASK XCHAL_EXTINT1_MASK
-#else
-#define ETHERNET_INTMASK 0
-#endif
-
-/* UART interrupt: */
-#ifdef XCHAL_EXTINT0_NUM
-#define UART16550_INTNUM XCHAL_EXTINT0_NUM
-#define UART16550_INTLEVEL XCHAL_EXTINT0_LEVEL
-#define UART16550_INTMASK XCHAL_EXTINT0_MASK
-#else
-#define UART16550_INTMASK 0
-#endif
-
-/* Audio output interrupt (I2S transmitter FIFO): */
-#ifdef XCHAL_EXTINT2_NUM
-#define AUDIO_I2S_OUT_INTNUM XCHAL_EXTINT2_NUM
-#define AUDIO_I2S_OUT_INTLEVEL XCHAL_EXTINT2_LEVEL
-#define AUDIO_I2S_OUT_INTMASK XCHAL_EXTINT2_MASK
-#else
-#define AUDIO_I2S_OUT_INTMASK 0
-#endif
-
-/* Audio input interrupt (I2S receiver FIFO): */
-#ifdef XCHAL_EXTINT3_NUM
-#define AUDIO_I2S_IN_INTNUM XCHAL_EXTINT3_NUM
-#define AUDIO_I2S_IN_INTLEVEL XCHAL_EXTINT3_LEVEL
-#define AUDIO_I2S_IN_INTMASK XCHAL_EXTINT3_MASK
-#else
-#define AUDIO_I2S_IN_INTMASK 0
-#endif
-
-/* I2C interrupt */
-#ifdef XCHAL_EXTINT4_NUM
-#define I2C_INTNUM XCHAL_EXTINT4_NUM
-#define I2C_INTLEVEL XCHAL_EXTINT4_LEVEL
-#define I2C_INTMASK XCHAL_EXTINT4_MASK
-#else
-#define I2C_INTMASK 0
-#endif
-
-/* USB interrupt */
-#ifdef XCHAL_EXTINT5_NUM
-#define USB_INTNUM XCHAL_EXTINT5_NUM
-#define USB_INTLEVEL XCHAL_EXTINT5_LEVEL
-#define USB_INTMASK XCHAL_EXTINT5_MASK
-#else
-#define USB_INTMASK 0
-#endif
-
-/*
- * Device addresses.
- *
- * Note: for endianness-independence, use 32-bit loads and stores for all
- * register accesses to Ethernet, UART and LED devices. Undefined bits
- * may need to be masked out if needed when reading if the actual register
- * size is smaller than 32 bits.
- *
- * Note: ML605 bus byte lanes are defined in terms of msbyte and lsbyte
- * relative to the processor. So 32-bit registers are accessed consistently
- * from both big and little endian processors. However, this means byte
- * sequences are not consistent between big and little endian processors.
- * This is fine for RAM, and for ROM if ROM is created for a specific
- * processor (and thus has correct byte sequences). However this may be
- * unexpected for Flash, which might contain a file-system that one wants
- * to use for multiple processor configurations (eg. the Flash might contain
- * the Ethernet card's address, endianness-independent application data, etc).
- * That is, byte sequences written in Flash by a core of a given endianness
- * will be byte-swapped when seen by a core of the other endianness.
- * Someone implementing an endianness-independent Flash file system will
- * likely handle this byte-swapping issue in the Flash driver software.
- */
-
-#define ML605_FLASH_MAXSIZE 0x01000000 /* 16 MB */
-#define ML605_FLASH_IOBLOCK_OFS 0x08000000
-
-#define KC705_FLASH_MAXSIZE 0x08000000 /* 128 MB */
-#define KC705_FLASH_IOBLOCK_OFS 0x00000000
-
-#if XTBOARD_IS_KC705
-#define XTBOARD_FLASH_MAXSIZE KC705_FLASH_MAXSIZE
-#define XTBOARD_FLASH_IO_OFS KC705_FLASH_IOBLOCK_OFS
-#else
-#define XTBOARD_FLASH_MAXSIZE ML605_FLASH_MAXSIZE
-#define XTBOARD_FLASH_IO_OFS ML605_FLASH_IOBLOCK_OFS
-#endif
-
-#ifdef XSHAL_IOBLOCK_BYPASS_PADDR
-
-/* Flash Memory: */
-# define XTBOARD_FLASH_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+XTBOARD_FLASH_IO_OFS)
-
-/* FPGA registers: */
-# define XTBOARD_FPGAREGS_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D020000)
-
-/* Ethernet controller/transceiver SONIC SN83934: */
-# define ETHERNET_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D030000)
-
-
-/* UART National-Semi PC16550D: */
-# define UART16550_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D050000)
-
-/* I2S transmitter */
-# define AUDIO_I2S_OUT_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D080000)
-
-/* I2S receiver */
-# define AUDIO_I2S_IN_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D088000)
-
-/* I2C master */
-# define I2C_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D090000)
-
-/* SPI controller */
-# define SPI_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D0A0000)
-
-/* Display controller Sunplus SPLC780D, 4bit mode,
- * LCD Display MYTech MOC-16216B-B: */
-# define SPLC780D_4BIT_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D0C0000)
-
-/* USB Controller */
-# define USB_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D0D0000)
-
-/* Ethernet buffer: */
-# define ETHERNET_BUFFER_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0D800000)
-
-#endif /* XSHAL_IOBLOCK_BYPASS_PADDR */
-
-/* These devices might be accessed cached: */
-#ifdef XSHAL_IOBLOCK_CACHED_PADDR
-# define XTBOARD_FLASH_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+XTBOARD_FLASH_IO_OFS)
-# define ETHERNET_BUFFER_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0x0D800000)
-#endif /* XSHAL_IOBLOCK_CACHED_PADDR */
-
-
-/*** Same thing over again, this time with virtual addresses: ***/
-
-#ifdef XSHAL_IOBLOCK_BYPASS_VADDR
-
-/* Flash Memory: */
-# define XTBOARD_FLASH_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+XTBOARD_FLASH_IO_OFS)
-
-/* FPGA registers: */
-# define XTBOARD_FPGAREGS_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D020000)
-
-/* Ethernet controller/transceiver SONIC SN83934: */
-# define ETHERNET_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D030000)
-
-
-/* UART National-Semi PC16550D: */
-# define UART16550_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D050000)
-
-/* I2S transmitter */
-# define AUDIO_I2S_OUT_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D080000)
-
-/* I2S receiver */
-# define AUDIO_I2S_IN_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D088000)
-
-/* I2C master */
-# define I2C_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D090000)
-
-/* SPI controller */
-# define SPI_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D0A0000)
-
-/* Display controller Sunplus SPLC780D, 4bit mode,
- * LCD Display MYTech MOC-16216B-B: */
-# define SPLC780D_4BIT_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D0C0000)
-
-/* USB Controller */
-# define USB_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D0D0000)
-
-/* Ethernet buffer: */
-# define ETHERNET_BUFFER_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0D800000)
-
-#endif /* XSHAL_IOBLOCK_BYPASS_VADDR */
-
-/* These devices might be accessed cached: */
-#ifdef XSHAL_IOBLOCK_CACHED_VADDR
-# define XTBOARD_FLASH_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+XTBOARD_FLASH_IO_OFS)
-# define ETHERNET_BUFFER_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0x0D800000)
-#endif /* XSHAL_IOBLOCK_CACHED_VADDR */
-
-
-/* System ROM: */
-#define XTBOARD_ROM_SIZE XSHAL_ROM_SIZE
-#ifdef XSHAL_ROM_VADDR
-#define XTBOARD_ROM_VADDR XSHAL_ROM_VADDR
-#endif
-#ifdef XSHAL_ROM_PADDR
-#define XTBOARD_ROM_PADDR XSHAL_ROM_PADDR
-#endif
-
-/* System RAM: */
-#define XTBOARD_RAM_SIZE XSHAL_RAM_SIZE
-#ifdef XSHAL_RAM_VADDR
-#define XTBOARD_RAM_VADDR XSHAL_RAM_VADDR
-#endif
-#ifdef XSHAL_RAM_PADDR
-#define XTBOARD_RAM_PADDR XSHAL_RAM_PADDR
-#endif
-#define XTBOARD_RAM_BYPASS_VADDR XSHAL_RAM_BYPASS_VADDR
-#define XTBOARD_RAM_BYPASS_PADDR XSHAL_RAM_BYPASS_PADDR
-
-
-
-/*
- * Things that depend on device addresses.
- */
-
-
-#define XTBOARD_CACHEATTR_WRITEBACK XSHAL_XT2000_CACHEATTR_WRITEBACK
-#define XTBOARD_CACHEATTR_WRITEALLOC XSHAL_XT2000_CACHEATTR_WRITEALLOC
-#define XTBOARD_CACHEATTR_WRITETHRU XSHAL_XT2000_CACHEATTR_WRITETHRU
-#define XTBOARD_CACHEATTR_BYPASS XSHAL_XT2000_CACHEATTR_BYPASS
-#define XTBOARD_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_DEFAULT
-
-#define XTBOARD_BUSINT_PIPE_REGIONS XSHAL_XT2000_PIPE_REGIONS
-#define XTBOARD_BUSINT_SDRAM_REGIONS XSHAL_XT2000_SDRAM_REGIONS
-
-
-/*
- * FPGA registers.
- * All these registers are normally accessed using 32-bit loads/stores.
- */
-
-/* Register offsets: */
-#define XTBOARD_DATECD_OFS 0x00 /* date code (read-only) */
-#define XTBOARD_CLKFRQ_OFS 0x04 /* clock frequency Hz (read-only) */
-#define XTBOARD_SYSLED_OFS 0x08 /* LEDs */
-#define XTBOARD_DIPSW_OFS 0x0C /* DIP switch bits (read-only) */
-#define XTBOARD_SWRST_OFS 0x10 /* software reset */
-
-/* Physical register addresses: */
-#ifdef XTBOARD_FPGAREGS_PADDR
-#define XTBOARD_DATECD_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_DATECD_OFS)
-#define XTBOARD_CLKFRQ_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_CLKFRQ_OFS)
-#define XTBOARD_SYSLED_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_SYSLED_OFS)
-#define XTBOARD_DIPSW_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_DIPSW_OFS)
-#define XTBOARD_SWRST_PADDR (XTBOARD_FPGAREGS_PADDR+XTBOARD_SWRST_OFS)
-#endif
-
-/* Virtual register addresses: */
-#ifdef XTBOARD_FPGAREGS_VADDR
-#define XTBOARD_DATECD_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_DATECD_OFS)
-#define XTBOARD_CLKFRQ_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_CLKFRQ_OFS)
-#define XTBOARD_SYSLED_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_SYSLED_OFS)
-#define XTBOARD_DIPSW_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_DIPSW_OFS)
-#define XTBOARD_SWRST_VADDR (XTBOARD_FPGAREGS_VADDR+XTBOARD_SWRST_OFS)
-/* Register access (for C code): */
-#define XTBOARD_DATECD_REG (*(volatile unsigned*) XTBOARD_DATECD_VADDR)
-#define XTBOARD_CLKFRQ_REG (*(volatile unsigned*) XTBOARD_CLKFRQ_VADDR)
-#define XTBOARD_SYSLED_REG (*(volatile unsigned*) XTBOARD_SYSLED_VADDR)
-#define XTBOARD_DIPSW_REG (*(volatile unsigned*) XTBOARD_DIPSW_VADDR)
-#define XTBOARD_SWRST_REG (*(volatile unsigned*) XTBOARD_SWRST_VADDR)
-#endif
-
-/* DATECD (date code; when core was built) bit fields: */
-/* BCD-coded month (01..12): */
-#define XTBOARD_DATECD_MONTH_SHIFT 24
-#define XTBOARD_DATECD_MONTH_BITS 8
-#define XTBOARD_DATECD_MONTH_MASK 0xFF000000
-/* BCD-coded day (01..31): */
-#define XTBOARD_DATECD_DAY_SHIFT 16
-#define XTBOARD_DATECD_DAY_BITS 8
-#define XTBOARD_DATECD_DAY_MASK 0x00FF0000
-/* BCD-coded year (2001..9999): */
-#define XTBOARD_DATECD_YEAR_SHIFT 0
-#define XTBOARD_DATECD_YEAR_BITS 16
-#define XTBOARD_DATECD_YEAR_MASK 0x0000FFFF
-
-/* SYSLED (system LED) bit fields: */
-
-/* LED control bits (off=0, on=1): */
-#define XTBOARD_SYSLED_USER_SHIFT 0
-#define XTBOARD_SYSLED_USER_BITS 2
-#define XTBOARD_SYSLED_USER_MASK 0x00000003
-
-/* DIP Switch SW? (left=sw1=lsb=bit0, right=sw4=msb=bit3; off=0, on=1): */
-/* DIP switch bit fields (bit2/sw3 is reserved and presently unused): */
-#if XTBOARD_IS_KC705
-#define XTBOARD_DIPSW_USER_SHIFT 0
-#define XTBOARD_DIPSW_USER_BITS 2
-#define XTBOARD_DIPSW_USER_MASK 0x00000003
-#define XTBOARD_DIPSW_BOOT_SHIFT 3
-#define XTBOARD_DIPSW_BOOT_BITS 1
-#define XTBOARD_DIPSW_BOOT_MASK 0x00000008
-#else /* ML605: */
-#define XTBOARD_DIPSW_USER_SHIFT 0
-#define XTBOARD_DIPSW_USER_BITS 6
-#define XTBOARD_DIPSW_USER_MASK 0x0000003F
-#define XTBOARD_DIPSW_BOOT_SHIFT 7
-#define XTBOARD_DIPSW_BOOT_BITS 1
-#define XTBOARD_DIPSW_BOOT_MASK 0x00000080
-#endif /*ML605*/
-#define XTBOARD_DIPSW_BOOT_RAM (0<
-
diff --git a/components/esp32/include/xtensa/xtutil.h b/components/esp32/include/xtensa/xtutil.h
deleted file mode 100644
index fb05c37057..0000000000
--- a/components/esp32/include/xtensa/xtutil.h
+++ /dev/null
@@ -1,61 +0,0 @@
-
-/* $Id$ */
-/*******************************************************************************/
-/* Copyright (c) 2001-2013 by Tensilica Inc. ALL RIGHTS RESERVED. */
-/* These coded instructions, statements, and computer programs are the */
-/* copyrighted works and confidential proprietary information of Tensilica Inc.*/
-/* They may not be modified, copied, reproduced, distributed, or disclosed to */
-/* third parties in any manner, medium, or form, in whole or in part, without */
-/* the prior written consent of Tensilica Inc. */
-/*******************************************************************************/
-
-#ifndef XTUTIL_H
-#define XTUTIL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include
-
-extern int xt_putchar(int c);
-extern int xt_puts(const char * s);
-extern void xt_putn(unsigned n);
-extern int xt_atoi(const char * s);
-extern int xt_printf(const char *fmt, ...);
-extern int xt_sprintf(char * buf, const char * fmt, ...);
-
-typedef int xt_output_fn(int *, int, const void *, int);
-extern xt_output_fn * xt_set_output_fn(xt_output_fn * fn);
-
-#ifdef XTUTIL_LIB
-
-// Only defined if building library
-
-typedef void (xt_outbuf_fn)(void *, char *, int);
-
-extern int xt_vprintf(xt_outbuf_fn * out, void * outarg, const char * fmt, va_list ap);
-
-#else
-
-// Only defined if building application and overriding
-
-#ifndef XTUTIL_NO_OVERRIDE
-
-#define putchar xt_putchar
-#define puts xt_puts
-#define putn xt_putn
-#define atoi xt_atoi
-#define printf xt_printf
-#define sprintf xt_sprintf
-
-#endif // XTUTIL_NO_OVERRIDE
-
-#endif // XTUTIL_LIB
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // XTUTIL_H
-
diff --git a/components/esp32/ipc.c b/components/esp32/ipc.c
index aedf4edb3b..6319a621d7 100644
--- a/components/esp32/ipc.c
+++ b/components/esp32/ipc.c
@@ -77,7 +77,7 @@ void esp_ipc_init()
{
s_ipc_mutex = xSemaphoreCreateMutex();
s_ipc_ack = xSemaphoreCreateBinary();
- char task_name[8];
+ char task_name[15];
for (int i = 0; i < portNUM_PROCESSORS; ++i) {
sprintf(task_name,"ipc%d",i);
s_ipc_sem[i] = xSemaphoreCreateBinary();
diff --git a/components/esp32/ld/esp32.common.ld b/components/esp32/ld/esp32.common.ld
index 73f592ef13..71ae220950 100644
--- a/components/esp32/ld/esp32.common.ld
+++ b/components/esp32/ld/esp32.common.ld
@@ -11,7 +11,7 @@ SECTIONS
. = ALIGN(4);
*(.rtc.literal .rtc.text)
*rtc_wake_stub*.*(.literal .text .literal.* .text.*)
- } >rtc_iram_seg
+ } > rtc_iram_seg
/* RTC slow memory holds RTC wake stub
data/rodata, including from any source file
@@ -35,9 +35,24 @@ SECTIONS
_rtc_bss_end = ABSOLUTE(.);
} > rtc_slow_seg
+ /* This section holds data that should not be initialized at power up
+ and will be retained during deep sleep. The section located in
+ RTC SLOW Memory area. User data marked with RTC_NOINIT_ATTR will be placed
+ into this section. See the file "esp_attr.h" for more information.
+ */
+ .rtc_noinit (NOLOAD):
+ {
+ . = ALIGN(4);
+ _rtc_noinit_start = ABSOLUTE(.);
+ *(.rtc_noinit .rtc_noinit.*)
+ . = ALIGN(4) ;
+ _rtc_noinit_end = ABSOLUTE(.);
+ } > rtc_slow_seg
+
/* Send .iram0 code to iram */
.iram0.vectors :
{
+ _iram_start = ABSOLUTE(.);
/* Vectors go to IRAM */
_init_start = ABSOLUTE(.);
/* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
@@ -71,11 +86,7 @@ SECTIONS
*(.init.literal)
*(.init)
_init_end = ABSOLUTE(.);
-
- /* This goes here, not at top of linker script, so addr2line finds it last,
- and uses it in preference to the first symbol in IRAM */
- _iram_start = ABSOLUTE(0);
- } > iram0_0_seg
+} > iram0_0_seg
.iram0.text :
{
@@ -90,18 +101,28 @@ SECTIONS
*libapp_trace.a:(.literal .text .literal.* .text.*)
*libxtensa-debug-module.a:eri.*(.literal .text .literal.* .text.*)
*librtc.a:(.literal .text .literal.* .text.*)
- *libsoc.a:(.literal .text .literal.* .text.*)
+ *libsoc.a:rtc_*.*(.literal .text .literal.* .text.*)
+ *libsoc.a:cpu_util.*(.literal .text .literal.* .text.*)
*libhal.a:(.literal .text .literal.* .text.*)
*libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*)
*libspi_flash.a:spi_flash_rom_patch.*(.literal .text .literal.* .text.*)
*libgcov.a:(.literal .text .literal.* .text.*)
INCLUDE esp32.spiram.rom-functions-iram.ld
_iram_text_end = ABSOLUTE(.);
+ _iram_end = ABSOLUTE(.);
} > iram0_0_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
+ _bt_data_start = ABSOLUTE(.);
+ *libbt.a:(.data .data.*)
+ . = ALIGN (4);
+ _bt_data_end = ABSOLUTE(.);
+ _btdm_data_start = ABSOLUTE(.);
+ *libbtdm_app.a:(.data .data.*)
+ . = ALIGN (4);
+ _btdm_data_end = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
@@ -124,13 +145,35 @@ SECTIONS
INCLUDE esp32.spiram.rom-functions-dram.ld
_data_end = ABSOLUTE(.);
. = ALIGN(4);
- } >dram0_0_seg
+ } > dram0_0_seg
+
+ /*This section holds data that should not be initialized at power up.
+ The section located in Internal SRAM memory region. The macro _NOINIT
+ can be used as attribute to place data into this section.
+ See the esp_attr.h file for more information.
+ */
+ .noinit (NOLOAD):
+ {
+ . = ALIGN(4);
+ _noinit_start = ABSOLUTE(.);
+ *(.noinit .noinit.*)
+ . = ALIGN(4) ;
+ _noinit_end = ABSOLUTE(.);
+ } > dram0_0_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
. = ALIGN (8);
_bss_start = ABSOLUTE(.);
+ _bt_bss_start = ABSOLUTE(.);
+ *libbt.a:(.bss .bss.* COMMON)
+ . = ALIGN (4);
+ _bt_bss_end = ABSOLUTE(.);
+ _btdm_bss_start = ABSOLUTE(.);
+ *libbtdm_app.a:(.bss .bss.* COMMON)
+ . = ALIGN (4);
+ _btdm_bss_end = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
@@ -147,8 +190,9 @@ SECTIONS
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
+ /* The heap starts right after end of this section */
_heap_start = ABSOLUTE(.);
- } >dram0_0_seg
+ } > dram0_0_seg
.flash.rodata :
{
@@ -186,6 +230,11 @@ SECTIONS
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
+ /* Addresses of memory regions reserved via
+ SOC_RESERVE_MEMORY_REGION() */
+ soc_reserved_memory_region_start = ABSOLUTE(.);
+ KEEP (*(.reserved_memory_address))
+ soc_reserved_memory_region_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
/* Literals are also RO data. */
_lit4_start = ABSOLUTE(.);
diff --git a/components/esp32/ld/esp32.peripherals.ld b/components/esp32/ld/esp32.peripherals.ld
index 3403ee8a8e..2dce0e0fcf 100644
--- a/components/esp32/ld/esp32.peripherals.ld
+++ b/components/esp32/ld/esp32.peripherals.ld
@@ -26,6 +26,7 @@ PROVIDE ( SPI3 = 0x3ff65000 );
PROVIDE ( SYSCON = 0x3ff66000 );
PROVIDE ( I2C1 = 0x3ff67000 );
PROVIDE ( SDMMC = 0x3ff68000 );
+PROVIDE ( CAN = 0x3ff6B000 );
PROVIDE ( MCPWM1 = 0x3ff6C000 );
PROVIDE ( I2S1 = 0x3ff6D000 );
PROVIDE ( UART2 = 0x3ff6E000 );
diff --git a/components/esp32/ld/esp32.rom.ld b/components/esp32/ld/esp32.rom.ld
index 8c458ff146..fdeda525fa 100644
--- a/components/esp32/ld/esp32.rom.ld
+++ b/components/esp32/ld/esp32.rom.ld
@@ -4,32 +4,22 @@ Generated for ROM with MD5sum:
ab8282ae908fe9e7a63fb2a4ac2df013 ../../rom_image/prorom.elf
*/
PROVIDE ( abort = 0x4000bba4 );
-PROVIDE ( __absvdi2 = 0x4006387c );
-PROVIDE ( __absvsi2 = 0x40063868 );
PROVIDE ( Add2SelfBigHex256 = 0x40015b7c );
PROVIDE ( AddBigHex256 = 0x40015b28 );
PROVIDE ( AddBigHexModP256 = 0x40015c98 );
-PROVIDE ( __adddf3 = 0x40002590 );
PROVIDE ( AddP256 = 0x40015c74 );
PROVIDE ( AddPdiv2_256 = 0x40015ce0 );
-PROVIDE ( __addsf3 = 0x400020e8 );
-PROVIDE ( __addvdi3 = 0x40002cbc );
-PROVIDE ( __addvsi3 = 0x40002c98 );
PROVIDE ( aes_128_cbc_decrypt = 0x4005cc7c );
PROVIDE ( aes_128_cbc_encrypt = 0x4005cc18 );
PROVIDE ( aes_unwrap = 0x4005ccf0 );
PROVIDE ( app_gpio_arg = 0x3ffe003c );
PROVIDE ( app_gpio_handler = 0x3ffe0040 );
-PROVIDE ( __ashldi3 = 0x4000c818 );
-PROVIDE ( __ashrdi3 = 0x4000c830 );
PROVIDE ( base64_decode = 0x4005ced8 );
PROVIDE ( base64_encode = 0x4005cdbc );
PROVIDE ( BasePoint_x_256 = 0x3ff97488 );
PROVIDE ( BasePoint_y_256 = 0x3ff97468 );
PROVIDE ( bigHexInversion256 = 0x400168f0 );
PROVIDE ( bigHexP256 = 0x3ff973bc );
-PROVIDE ( __bswapdi2 = 0x400649c4 );
-PROVIDE ( __bswapsi2 = 0x4006499c );
PROVIDE ( btdm_r_ble_bt_handler_tab_p_get = 0x40019b0c );
PROVIDE ( btdm_r_btdm_option_data_p_get = 0x40010004 );
PROVIDE ( btdm_r_btdm_rom_version_get = 0x40010078 );
@@ -50,14 +40,8 @@ PROVIDE ( cache_sram_mmu_set_rom = 0x400097f4 );
/* This is static function, but can be used, not generated by script*/
PROVIDE ( calc_rtc_memory_crc = 0x40008170 );
PROVIDE ( calloc = 0x4000bee4 );
-PROVIDE ( _calloc_r = 0x4000bbf8 );
PROVIDE ( __clear_cache = 0x40063860 );
PROVIDE ( _close_r = 0x4000bd3c );
-PROVIDE ( __clrsbdi2 = 0x40064a38 );
-PROVIDE ( __clrsbsi2 = 0x40064a20 );
-PROVIDE ( __clzdi2 = 0x4000ca50 );
-PROVIDE ( __clzsi2 = 0x4000c7e8 );
-PROVIDE ( __cmpdi2 = 0x40063820 );
PROVIDE ( co_default_bdaddr = 0x3ffae704 );
PROVIDE ( co_null_bdaddr = 0x3ffb80e0 );
PROVIDE ( co_sca2ppm = 0x3ff971e8 );
@@ -69,8 +53,6 @@ PROVIDE ( crc8_be = 0x4005d114 );
PROVIDE ( crc8_le = 0x4005d0e0 );
PROVIDE ( _ctype_ = 0x3ff96354 );
PROVIDE ( __ctype_ptr__ = 0x3ff96350 );
-PROVIDE ( __ctzdi2 = 0x4000ca64 );
-PROVIDE ( __ctzsi2 = 0x4000c7f0 );
PROVIDE ( _data_end_rom = 0x4000d5c8 );
PROVIDE ( _data_end_btdm_rom = 0x4000d4f8 );
PROVIDE ( _data_start_rom = 0x4000d4f8 );
@@ -103,49 +85,21 @@ PROVIDE ( dh_group2_generator = 0x3ff9ada2 );
PROVIDE ( dh_group2_prime = 0x3ff9ad22 );
PROVIDE ( dh_group5_generator = 0x3ff9ad21 );
PROVIDE ( dh_group5_prime = 0x3ff9ac61 );
-PROVIDE ( __divdc3 = 0x40064460 );
-PROVIDE ( __divdf3 = 0x40002954 );
-PROVIDE ( __divdi3 = 0x4000ca84 );
-PROVIDE ( __divsc3 = 0x40064200 );
-PROVIDE ( __divsf3 = 0x4000234c );
-PROVIDE ( __divsi3 = 0x4000c7b8 );
PROVIDE ( g_rom_spiflash_dummy_len_plus = 0x3ffae290 );
PROVIDE ( ecc_env = 0x3ffb8d60 );
PROVIDE ( ecc_Jacobian_InfinityPoint256 = 0x3ff972e8 );
PROVIDE ( em_buf_env = 0x3ffb8d74 );
PROVIDE ( environ = 0x3ffae0b4 );
-PROVIDE ( __eqdf2 = 0x400636a8 );
-PROVIDE ( __eqsf2 = 0x40063374 );
PROVIDE ( esp_crc8 = 0x4005d144 );
PROVIDE ( _etext = 0x4000d66c );
PROVIDE ( ets_readySet_ = 0x3ffe01f0 );
PROVIDE ( ets_startup_callback = 0x3ffe0404 );
PROVIDE ( exc_cause_table = 0x3ff991d0 );
PROVIDE ( _exit_r = 0x4000bd28 );
-PROVIDE ( __extendsfdf2 = 0x40002c34 );
-PROVIDE ( __ffsdi2 = 0x4000ca2c );
-PROVIDE ( __ffssi2 = 0x4000c804 );
-PROVIDE ( __fixdfdi = 0x40002ac4 );
-PROVIDE ( __fixdfsi = 0x40002a78 );
-PROVIDE ( __fixsfdi = 0x4000244c );
-PROVIDE ( __fixsfsi = 0x4000240c );
-PROVIDE ( __fixunsdfsi = 0x40002b30 );
-PROVIDE ( __fixunssfdi = 0x40002504 );
-PROVIDE ( __fixunssfsi = 0x400024ac );
-PROVIDE ( __floatdidf = 0x4000c988 );
-PROVIDE ( __floatdisf = 0x4000c8c0 );
-PROVIDE ( __floatsidf = 0x4000c944 );
-PROVIDE ( __floatsisf = 0x4000c870 );
-PROVIDE ( __floatundidf = 0x4000c978 );
-PROVIDE ( __floatundisf = 0x4000c8b0 );
-PROVIDE ( __floatunsidf = 0x4000c938 );
-PROVIDE ( __floatunsisf = 0x4000c864 );
PROVIDE ( free = 0x4000beb8 );
PROVIDE ( _free_r = 0x4000bbcc );
PROVIDE ( _fstat_r = 0x4000bccc );
PROVIDE ( __gcc_bcmp = 0x40064a70 );
-PROVIDE ( __gedf2 = 0x40063768 );
-PROVIDE ( __gesf2 = 0x4006340c );
PROVIDE ( _getpid_r = 0x4000bcfc );
PROVIDE ( __getreent = 0x4000be8c );
PROVIDE ( _gettimeofday_r = 0x4000bc58 );
@@ -155,8 +109,6 @@ PROVIDE ( GF_Point_Jacobian_To_Affine256 = 0x40016b0c );
PROVIDE ( _global_impure_ptr = 0x3ffae0b0 );
PROVIDE ( g_phyFuns_instance = 0x3ffae0c4 );
PROVIDE ( g_rom_flashchip = 0x3ffae270 );
-PROVIDE ( __gtdf2 = 0x400636dc );
-PROVIDE ( __gtsf2 = 0x400633a0 );
PROVIDE ( gTxMsg = 0x3ffe0050 );
PROVIDE ( hci_cmd_desc_root_tab = 0x3ff976d4 );
PROVIDE ( hci_cmd_desc_tab_ctrl_bb = 0x3ff97b70 );
@@ -202,8 +154,6 @@ PROVIDE ( ld_env = 0x3ffb9510 );
PROVIDE ( ld_pcm_settings_dft = 0x3ff98a0c );
PROVIDE ( ld_sched_params = 0x3ffb96c0 );
PROVIDE ( ld_sync_train_channels = 0x3ff98a3c );
-PROVIDE ( __ledf2 = 0x40063704 );
-PROVIDE ( __lesf2 = 0x400633c0 );
PROVIDE ( _link_r = 0x4000bc9c );
PROVIDE ( llc_default_handler = 0x3ff98b3c );
PROVIDE ( llc_default_state_tab_p_get = 0x40046058 );
@@ -256,9 +206,6 @@ PROVIDE ( _lock_release_recursive = 0x4000be78 );
PROVIDE ( _lock_try_acquire = 0x4000be3c );
PROVIDE ( _lock_try_acquire_recursive = 0x4000be50 );
PROVIDE ( _lseek_r = 0x4000bd8c );
-PROVIDE ( __lshrdi3 = 0x4000c84c );
-PROVIDE ( __ltdf2 = 0x40063790 );
-PROVIDE ( __ltsf2 = 0x4006342c );
PROVIDE ( malloc = 0x4000bea0 );
PROVIDE ( _malloc_r = 0x4000bbb4 );
PROVIDE ( maxSecretKey_256 = 0x3ff97448 );
@@ -268,43 +215,19 @@ PROVIDE ( MD5Init = 0x4005da7c );
PROVIDE ( MD5Update = 0x4005da9c );
PROVIDE ( md5_vector = 0x4005db80 );
PROVIDE ( mmu_init = 0x400095a4 );
-PROVIDE ( __moddi3 = 0x4000cd4c );
-PROVIDE ( __modsi3 = 0x4000c7c0 );
PROVIDE ( __month_lengths = 0x3ff9609c );
-PROVIDE ( __muldc3 = 0x40063bf4 );
-PROVIDE ( __muldf3 = 0x4006358c );
-PROVIDE ( __muldi3 = 0x4000c9fc );
-PROVIDE ( __mulsc3 = 0x40063934 );
-PROVIDE ( __mulsf3 = 0x400632c8 );
-PROVIDE ( __mulsi3 = 0x4000c7b0 );
PROVIDE ( MultiplyBigHexByUint32_256 = 0x40016214 );
PROVIDE ( MultiplyBigHexModP256 = 0x400160b8 );
PROVIDE ( MultiplyByU32ModP256 = 0x40015fdc );
PROVIDE ( multofup = 0x4000ab8c );
-PROVIDE ( __mulvdi3 = 0x40002d78 );
-PROVIDE ( __mulvsi3 = 0x40002d60 );
PROVIDE ( mz_adler32 = 0x4005edbc );
PROVIDE ( mz_crc32 = 0x4005ee88 );
PROVIDE ( mz_free = 0x4005eed4 );
-PROVIDE ( __nedf2 = 0x400636a8 );
-PROVIDE ( __negdf2 = 0x400634a0 );
-PROVIDE ( __negdi2 = 0x4000ca14 );
-PROVIDE ( __negsf2 = 0x400020c0 );
-PROVIDE ( __negvdi2 = 0x40002e98 );
-PROVIDE ( __negvsi2 = 0x40002e78 );
-PROVIDE ( __nesf2 = 0x40063374 );
PROVIDE ( notEqual256 = 0x40015b04 );
-PROVIDE ( __nsau_data = 0x3ff96544 );
PROVIDE ( one_bits = 0x3ff971f8 );
PROVIDE ( _open_r = 0x4000bd54 );
-PROVIDE ( __paritysi2 = 0x40002f3c );
PROVIDE ( pbkdf2_sha1 = 0x40060ba4 );
PROVIDE ( phy_get_romfuncs = 0x40004100 );
-PROVIDE ( __popcountdi2 = 0x40002ef8 );
-PROVIDE ( __popcountsi2 = 0x40002ed0 );
-PROVIDE ( __popcount_tab = 0x3ff96544 );
-PROVIDE ( __powidf2 = 0x400638d4 );
-PROVIDE ( __powisf2 = 0x4006389c );
PROVIDE ( _Pri_4_HandlerAddress = 0x3ffe0648 );
PROVIDE ( _Pri_5_HandlerAddress = 0x3ffe064c );
PROVIDE ( r_btdm_option_data = 0x3ffae6e0 );
@@ -762,7 +685,14 @@ PROVIDE ( lmp_io_cap_req_handler = 0x4002c7a4 );
PROVIDE ( ld_acl_tx_packet_type_select = 0x4002fb40 );
PROVIDE ( ld_acl_sched = 0x40033268 );
PROVIDE ( ld_acl_sniff_sched = 0x4003340c );
+PROVIDE ( ld_acl_rx = 0x4003274c );
+PROVIDE ( ld_acl_tx = 0x4002ffdc );
+PROVIDE ( ld_acl_rx_sync = 0x4002fbec );
+PROVIDE ( ld_acl_rx_sync2 = 0x4002fd8c );
+PROVIDE ( ld_acl_rx_no_sync = 0x4002fe78 );
+PROVIDE ( ld_sco_modify = 0x40031778 );
PROVIDE ( lm_cmd_cmp_send = 0x40051838 );
+PROVIDE ( ld_sco_frm_cbk = 0x400349dc );
PROVIDE ( r_ld_acl_active_hop_types_get = 0x40036e10 );
PROVIDE ( r_ld_acl_afh_confirm = 0x40036d40 );
PROVIDE ( r_ld_acl_afh_prepare = 0x40036c84 );
@@ -1418,15 +1348,11 @@ PROVIDE ( _start = 0x40000704 );
PROVIDE ( start_tb_console = 0x4005a980 );
PROVIDE ( _stat_r = 0x4000bcb4 );
PROVIDE ( _stext = 0x40000560 );
-PROVIDE ( __subdf3 = 0x400026e4 );
-PROVIDE ( __subsf3 = 0x400021d0 );
PROVIDE ( SubtractBigHex256 = 0x40015bcc );
PROVIDE ( SubtractBigHexMod256 = 0x40015e8c );
PROVIDE ( SubtractBigHexUint32_256 = 0x40015f8c );
PROVIDE ( SubtractFromSelfBigHex256 = 0x40015c20 );
PROVIDE ( SubtractFromSelfBigHexSign256 = 0x40015dc8 );
-PROVIDE ( __subvdi3 = 0x40002d20 );
-PROVIDE ( __subvsi3 = 0x40002cf8 );
PROVIDE ( sw_to_hw = 0x3ffb8d40 );
PROVIDE ( syscall_table_ptr_app = 0x3ffae020 );
PROVIDE ( syscall_table_ptr_pro = 0x3ffae024 );
@@ -1444,20 +1370,9 @@ PROVIDE ( _timezone = 0x3ffae0a0 );
PROVIDE ( tinfl_decompress = 0x4005ef30 );
PROVIDE ( tinfl_decompress_mem_to_callback = 0x40060090 );
PROVIDE ( tinfl_decompress_mem_to_mem = 0x40060050 );
-PROVIDE ( __truncdfsf2 = 0x40002b90 );
PROVIDE ( _tzname = 0x3ffae030 );
PROVIDE ( UartDev = 0x3ffe019c );
-PROVIDE ( __ucmpdi2 = 0x40063840 );
-PROVIDE ( __udivdi3 = 0x4000cff8 );
-PROVIDE ( __udivmoddi4 = 0x40064ab0 );
-PROVIDE ( __udivsi3 = 0x4000c7c8 );
-PROVIDE ( __udiv_w_sdiv = 0x40064aa8 );
-PROVIDE ( __umoddi3 = 0x4000d280 );
-PROVIDE ( __umodsi3 = 0x4000c7d0 );
-PROVIDE ( __umulsidi3 = 0x4000c7d8 );
PROVIDE ( _unlink_r = 0x4000bc84 );
-PROVIDE ( __unorddf2 = 0x400637f4 );
-PROVIDE ( __unordsf2 = 0x40063478 );
PROVIDE ( user_code_start = 0x3ffe0400 );
PROVIDE ( veryBigHexP256 = 0x3ff9736c );
PROVIDE ( __wctomb = 0x3ff96540 );
diff --git a/components/esp32/ld/esp32.rom.libgcc.ld b/components/esp32/ld/esp32.rom.libgcc.ld
new file mode 100644
index 0000000000..51448b3327
--- /dev/null
+++ b/components/esp32/ld/esp32.rom.libgcc.ld
@@ -0,0 +1,91 @@
+__absvdi2 = 0x4006387c;
+__absvsi2 = 0x40063868;
+__adddf3 = 0x40002590;
+__addsf3 = 0x400020e8;
+__addvdi3 = 0x40002cbc;
+__addvsi3 = 0x40002c98;
+__ashldi3 = 0x4000c818;
+__ashrdi3 = 0x4000c830;
+__bswapdi2 = 0x40064b08;
+__bswapsi2 = 0x40064ae0;
+__clrsbdi2 = 0x40064b7c;
+__clrsbsi2 = 0x40064b64;
+__clzdi2 = 0x4000ca50;
+__clzsi2 = 0x4000c7e8;
+__cmpdi2 = 0x40063820;
+__ctzdi2 = 0x4000ca64;
+__ctzsi2 = 0x4000c7f0;
+__divdc3 = 0x400645a4;
+__divdf3 = 0x40002954;
+__divdi3 = 0x4000ca84;
+__divsc3 = 0x4006429c;
+__divsf3 = 0x4000234c;
+__divsi3 = 0x4000c7b8;
+__eqdf2 = 0x400636a8;
+__eqsf2 = 0x40063374;
+__extendsfdf2 = 0x40002c34;
+__ffsdi2 = 0x4000ca2c;
+__ffssi2 = 0x4000c804;
+__fixdfdi = 0x40002ac4;
+__fixdfsi = 0x40002a78;
+__fixsfdi = 0x4000244c;
+__fixsfsi = 0x4000240c;
+__fixunsdfsi = 0x40002b30;
+__fixunssfdi = 0x40002504;
+__fixunssfsi = 0x400024ac;
+__floatdidf = 0x4000c988;
+__floatdisf = 0x4000c8c0;
+__floatsidf = 0x4000c944;
+__floatsisf = 0x4000c870;
+__floatundidf = 0x4000c978;
+__floatundisf = 0x4000c8b0;
+__floatunsidf = 0x4000c938;
+__floatunsisf = 0x4000c864;
+__gedf2 = 0x40063768;
+__gesf2 = 0x4006340c;
+__gtdf2 = 0x400636dc;
+__gtsf2 = 0x400633a0;
+__ledf2 = 0x40063704;
+__lesf2 = 0x400633c0;
+__lshrdi3 = 0x4000c84c;
+__ltdf2 = 0x40063790;
+__ltsf2 = 0x4006342c;
+__moddi3 = 0x4000cd4c;
+__modsi3 = 0x4000c7c0;
+__muldc3 = 0x40063c90;
+__muldf3 = 0x4006358c;
+__muldi3 = 0x4000c9fc;
+__mulsc3 = 0x40063944;
+__mulsf3 = 0x400632c8;
+__mulsi3 = 0x4000c7b0;
+__mulvdi3 = 0x40002d78;
+__mulvsi3 = 0x40002d60;
+__nedf2 = 0x400636a8;
+__negdf2 = 0x400634a0;
+__negdi2 = 0x4000ca14;
+__negsf2 = 0x400020c0;
+__negvdi2 = 0x40002e98;
+__negvsi2 = 0x40002e78;
+__nesf2 = 0x40063374;
+__nsau_data = 0x3ff96544;
+__paritysi2 = 0x40002f3c;
+__popcount_tab = 0x3ff96544;
+__popcountdi2 = 0x40002ef8;
+__popcountsi2 = 0x40002ed0;
+__powidf2 = 0x400638e4;
+__powisf2 = 0x4006389c;
+__subdf3 = 0x400026e4;
+__subsf3 = 0x400021d0;
+__subvdi3 = 0x40002d20;
+__subvsi3 = 0x40002cf8;
+__truncdfsf2 = 0x40002b90;
+__ucmpdi2 = 0x40063840;
+__udiv_w_sdiv = 0x40064bec;
+__udivdi3 = 0x4000cff8;
+__udivmoddi4 = 0x40064bf4;
+__udivsi3 = 0x4000c7c8;
+__umoddi3 = 0x4000d280;
+__umodsi3 = 0x4000c7d0;
+__umulsidi3 = 0x4000c7d8;
+__unorddf2 = 0x400637f4;
+__unordsf2 = 0x40063478;
diff --git a/components/esp32/lib b/components/esp32/lib
index f56b7bd412..3a57e71988 160000
--- a/components/esp32/lib
+++ b/components/esp32/lib
@@ -1 +1 @@
-Subproject commit f56b7bd4127aa01dbd50eb8ac3c637690bd98f84
+Subproject commit 3a57e719887cfa3f72abc27e7d3102800cd7eb65
diff --git a/components/esp32/panic.c b/components/esp32/panic.c
index 83bc657f1a..5a000574be 100644
--- a/components/esp32/panic.c
+++ b/components/esp32/panic.c
@@ -30,6 +30,7 @@
#include "soc/timer_group_reg.h"
#include "soc/cpu.h"
#include "soc/rtc.h"
+#include "soc/rtc_wdt.h"
#include "esp_gdbstub.h"
#include "esp_panic.h"
@@ -40,6 +41,7 @@
#include "esp_cache_err_int.h"
#include "esp_app_trace.h"
#include "esp_system.h"
+#include "sdkconfig.h"
#if CONFIG_SYSVIEW_ENABLE
#include "SEGGER_RTT.h"
#endif
@@ -312,7 +314,7 @@ void xt_unhandled_exception(XtExcFrame *frame)
} else {
panicPutStr("Unknown");
}
- panicPutStr(")\r\n");
+ panicPutStr(")");
if (esp_cpu_in_ocd_debug_mode()) {
panicPutStr(" at pc=");
panicPutHex(frame->pc);
@@ -373,32 +375,6 @@ static inline void disableAllWdts()
TIMERG1.wdt_wprotect = 0;
}
-static void esp_panic_wdt_start()
-{
- if (REG_GET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN)) {
- return;
- }
- WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
- WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1);
- REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, 7);
- REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_CPU_RESET_LENGTH, 7);
- REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_RESET_SYSTEM);
- // 64KB of core dump data (stacks of about 30 tasks) will produce ~85KB base64 data.
- // @ 115200 UART speed it will take more than 6 sec to print them out.
- WRITE_PERI_REG(RTC_CNTL_WDTCONFIG1_REG, rtc_clk_slow_freq_get_hz() * 7);
- REG_SET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN);
- WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
-}
-
-void esp_panic_wdt_stop()
-{
- WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
- WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1);
- REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_OFF);
- REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN);
- WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
-}
-
static void esp_panic_dig_reset() __attribute__((noreturn));
static void esp_panic_dig_reset()
@@ -527,7 +503,18 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame)
int core_id = xPortGetCoreID();
// start panic WDT to restart system if we hang in this handler
- esp_panic_wdt_start();
+ if (!rtc_wdt_is_on()) {
+ rtc_wdt_protect_off();
+ rtc_wdt_disable();
+ rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us);
+ rtc_wdt_set_length_of_reset_signal(RTC_WDT_CPU_RESET_SIG, RTC_WDT_LENGTH_3_2us);
+ rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_SYSTEM);
+ // 64KB of core dump data (stacks of about 30 tasks) will produce ~85KB base64 data.
+ // @ 115200 UART speed it will take more than 6 sec to print them out.
+ rtc_wdt_set_time(RTC_WDT_STAGE0, 7000);
+ rtc_wdt_enable();
+ rtc_wdt_protect_on();
+ }
//Feed the watchdogs, so they will give us time to print out debug info
reconfigureAllWdts();
@@ -552,7 +539,7 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame)
#if CONFIG_ESP32_PANIC_GDBSTUB
disableAllWdts();
- esp_panic_wdt_stop();
+ rtc_wdt_disable();
panicPutStr("Entering gdb stub now.\r\n");
esp_gdbstub_panic_handler(frame);
#else
@@ -573,7 +560,7 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame)
reconfigureAllWdts();
}
#endif /* CONFIG_ESP32_ENABLE_COREDUMP */
- esp_panic_wdt_stop();
+ rtc_wdt_disable();
#if CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT
panicPutStr("Rebooting...\r\n");
if (frame->exccause != PANIC_RSN_CACHEERR) {
@@ -653,7 +640,11 @@ void esp_clear_watchpoint(int no)
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression)
{
- ets_printf("ESP_ERROR_CHECK failed: esp_err_t 0x%x at 0x%08x\n", rc, (intptr_t)__builtin_return_address(0) - 3);
+ ets_printf("ESP_ERROR_CHECK failed: esp_err_t 0x%x", rc);
+#ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP
+ ets_printf(" (%s)", esp_err_to_name(rc));
+#endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP
+ ets_printf(" at 0x%08x\n", (intptr_t)__builtin_return_address(0) - 3);
if (spi_flash_cache_enabled()) { // strings may be in flash cache
ets_printf("file: \"%s\" line %d\nfunc: %s\nexpression: %s\n", file, line, function, expression);
}
diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c
index 314f142683..2da98c31b0 100644
--- a/components/esp32/phy_init.c
+++ b/components/esp32/phy_init.c
@@ -133,6 +133,8 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, esp_phy_calibrat
extern esp_err_t wifi_osi_funcs_register(wifi_osi_funcs_t *osi_funcs);
status = wifi_osi_funcs_register(&g_wifi_osi_funcs);
if(status != ESP_OK) {
+ ESP_LOGE(TAG, "failed to register wifi os adapter, ret(%d)", status);
+ _lock_release(&s_phy_rf_init_lock);
return ESP_FAIL;
}
coex_bt_high_prio();
@@ -491,7 +493,6 @@ static esp_err_t load_cal_data_from_nvs_handle(nvs_handle handle,
ESP_LOGD(TAG, "%s: invalid length of cal_data (%d)", __func__, length);
return ESP_ERR_INVALID_SIZE;
}
- memcpy(out_cal_data->mac, sta_mac, 6);
return ESP_OK;
}
@@ -547,6 +548,7 @@ void esp_phy_load_cal_and_init(phy_rf_module_t module)
#ifdef CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE
esp_phy_calibration_mode_t calibration_mode = PHY_RF_CAL_PARTIAL;
+ uint8_t sta_mac[6];
if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) {
calibration_mode = PHY_RF_CAL_NONE;
}
@@ -556,6 +558,8 @@ void esp_phy_load_cal_and_init(phy_rf_module_t module)
calibration_mode = PHY_RF_CAL_FULL;
}
+ esp_efuse_mac_get_default(sta_mac);
+ memcpy(cal_data->mac, sta_mac, 6);
esp_phy_rf_init(init_data, calibration_mode, cal_data, module);
if (calibration_mode != PHY_RF_CAL_NONE && err != ESP_OK) {
diff --git a/components/esp32/sleep_modes.c b/components/esp32/sleep_modes.c
index 65d0f05683..91713ad6bb 100644
--- a/components/esp32/sleep_modes.c
+++ b/components/esp32/sleep_modes.c
@@ -32,6 +32,7 @@
#include "soc/spi_reg.h"
#include "soc/sens_reg.h"
#include "soc/dport_reg.h"
+#include "soc/rtc_wdt.h"
#include "driver/rtc_io.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@@ -141,6 +142,13 @@ void esp_deep_sleep(uint64_t time_in_us)
esp_deep_sleep_start();
}
+static void IRAM_ATTR flush_uarts()
+{
+ for (int i = 0; i < 3; ++i) {
+ uart_tx_wait_idle(i);
+ }
+}
+
static void IRAM_ATTR suspend_uarts()
{
for (int i = 0; i < 3; ++i) {
@@ -160,8 +168,14 @@ static void IRAM_ATTR resume_uarts()
static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
{
- // Stop UART output so that output is not lost due to APB frequency change
- suspend_uarts();
+ // Stop UART output so that output is not lost due to APB frequency change.
+ // For light sleep, suspend UART output — it will resume after wakeup.
+ // For deep sleep, wait for the contents of UART FIFO to be sent.
+ if (pd_flags & RTC_SLEEP_PD_DIG) {
+ flush_uarts();
+ } else {
+ suspend_uarts();
+ }
// Save current frequency and switch to XTAL
rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get();
@@ -203,7 +217,7 @@ void IRAM_ATTR esp_deep_sleep_start()
{
// record current RTC time
s_config.rtc_ticks_at_sleep_start = rtc_time_get();
-
+ esp_sync_counters_rtc_and_frc();
// Configure wake stub
if (esp_get_deep_sleep_wake_stub() == NULL) {
esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep);
@@ -225,27 +239,6 @@ void IRAM_ATTR esp_deep_sleep_start()
}
}
-static void rtc_wdt_enable(int time_ms)
-{
- WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
- WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1);
- REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, 7);
- REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_CPU_RESET_LENGTH, 7);
- REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_RESET_RTC);
- WRITE_PERI_REG(RTC_CNTL_WDTCONFIG1_REG, rtc_clk_slow_freq_get_hz() * time_ms / 1000);
- SET_PERI_REG_MASK(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN | RTC_CNTL_WDT_PAUSE_IN_SLP);
- WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
-}
-
-static void rtc_wdt_disable()
-{
- WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
- WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1);
- REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_OFF);
- REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN);
- WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
-}
-
/**
* Helper function which handles entry to and exit from light sleep
* Placed into IRAM as flash may need some time to be powered on.
@@ -313,7 +306,17 @@ esp_err_t esp_light_sleep_start()
rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config();
// Safety net: enable WDT in case exit from light sleep fails
- rtc_wdt_enable(1000);
+ bool wdt_was_enabled = rtc_wdt_is_on(); // If WDT was enabled in the user code, then do not change it here.
+ if (!wdt_was_enabled) {
+ rtc_wdt_protect_off();
+ rtc_wdt_disable();
+ rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us);
+ rtc_wdt_set_length_of_reset_signal(RTC_WDT_CPU_RESET_SIG, RTC_WDT_LENGTH_3_2us);
+ rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_RTC);
+ rtc_wdt_set_time(RTC_WDT_STAGE0, 1000);
+ rtc_wdt_enable();
+ rtc_wdt_protect_on();
+ }
// Enter sleep, then wait for flash to be ready on wakeup
esp_err_t err = esp_light_sleep_inner(pd_flags,
@@ -339,7 +342,9 @@ esp_err_t esp_light_sleep_start()
esp_timer_impl_unlock();
DPORT_STALL_OTHER_CPU_END();
- rtc_wdt_disable();
+ if (!wdt_was_enabled) {
+ rtc_wdt_disable();
+ }
portEXIT_CRITICAL(&light_sleep_lock);
return err;
}
@@ -428,9 +433,10 @@ touch_pad_t esp_sleep_get_touchpad_wakeup_status()
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TOUCHPAD) {
return TOUCH_PAD_MAX;
}
- uint32_t touch_mask = REG_GET_FIELD(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN);
- assert(touch_mask != 0 && "wakeup reason is RTC_TOUCH_TRIG_EN but SENS_TOUCH_MEAS_EN is zero");
- return (touch_pad_t) (__builtin_ffs(touch_mask) - 1);
+ touch_pad_t pad_num;
+ esp_err_t ret = touch_pad_get_wakeup_status(&pad_num);
+ assert(ret == ESP_OK && "wakeup reason is RTC_TOUCH_TRIG_EN but SENS_TOUCH_MEAS_EN is zero");
+ return pad_num;
}
esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
@@ -465,8 +471,7 @@ static void ext0_wakeup_prepare()
if (desc->rtc_num == rtc_gpio_num) {
REG_SET_BIT(desc->reg, desc->mux);
SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func);
- REG_SET_BIT(desc->reg, desc->slpsel);
- REG_SET_BIT(desc->reg, desc->slpie);
+ REG_SET_BIT(desc->reg, desc->ie);
break;
}
}
@@ -508,16 +513,13 @@ static void ext1_wakeup_prepare()
// Route pad to RTC
REG_SET_BIT(desc->reg, desc->mux);
SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func);
+ // set input enable in sleep mode
+ REG_SET_BIT(desc->reg, desc->ie);
// Pad configuration depends on RTC_PERIPH state in sleep mode
- if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_ON) {
- // set input enable in sleep mode
- REG_SET_BIT(desc->reg, desc->slpie);
- // allow sleep status signal to control IE/SLPIE mux
- REG_SET_BIT(desc->reg, desc->slpsel);
- } else {
- // RTC_PERIPH will be disabled, so need to enable input and
- // lock pad configuration. Pullups/pulldowns also need to be disabled.
- REG_SET_BIT(desc->reg, desc->ie);
+ if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) {
+ // RTC_PERIPH will be powered down, so RTC_IO_ registers will
+ // loose their state. Lock pad configuration.
+ // Pullups/pulldowns also need to be disabled.
REG_CLR_BIT(desc->reg, desc->pulldown);
REG_CLR_BIT(desc->reg, desc->pullup);
REG_SET_BIT(RTC_CNTL_HOLD_FORCE_REG, desc->hold_force);
@@ -599,9 +601,9 @@ static uint32_t get_power_down_flags()
// These labels are defined in the linker script:
extern int _rtc_data_start, _rtc_data_end, _rtc_bss_start, _rtc_bss_end;
- if (s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] == ESP_PD_OPTION_AUTO ||
- &_rtc_data_end > &_rtc_data_start ||
- &_rtc_bss_end > &_rtc_bss_start) {
+ if ((s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] == ESP_PD_OPTION_AUTO) &&
+ (&_rtc_data_end > &_rtc_data_start || &_rtc_bss_end > &_rtc_bss_start ||
+ (s_config.wakeup_triggers & RTC_ULP_TRIG_EN))) {
s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] = ESP_PD_OPTION_ON;
}
diff --git a/components/esp32/spiram.c b/components/esp32/spiram.c
index dccc3bc33e..72198734e1 100644
--- a/components/esp32/spiram.c
+++ b/components/esp32/spiram.c
@@ -19,10 +19,12 @@ we add more types of external RAM memory, this can be made into a more intellige
#include
#include
+#include
#include "sdkconfig.h"
#include "esp_attr.h"
#include "esp_err.h"
+#include "esp_spiram.h"
#include "spiram_psram.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
@@ -102,6 +104,39 @@ void IRAM_ATTR esp_spiram_init_cache()
#endif
}
+esp_spiram_volt_t esp_spiram_get_chip_volt()
+{
+ if (!spiram_inited) {
+ ESP_LOGE(TAG, "SPI RAM not initialized");
+ return ESP_SPIRAM_VOLT_INVALID;
+ }
+ psram_volt_t volt = psram_get_volt();
+ switch (volt) {
+ case PSRAM_VOLT_1V8:
+ return ESP_SPIRAM_VOLT_1V8;
+ case PSRAM_VOLT_3V3:
+ return ESP_SPIRAM_VOLT_3V3;
+ default:
+ return ESP_SPIRAM_VOLT_INVALID;
+ }
+}
+
+esp_spiram_size_t esp_spiram_get_chip_size()
+{
+ if (!spiram_inited) {
+ ESP_LOGE(TAG, "SPI RAM not initialized");
+ return ESP_SPIRAM_SIZE_INVALID;
+ }
+ psram_size_t psram_size = psram_get_size();
+ switch (psram_size) {
+ case PSRAM_SIZE_32MBITS:
+ return ESP_SPIRAM_SIZE_32MBITS;
+ case PSRAM_SIZE_64MBITS:
+ return ESP_SPIRAM_SIZE_64MBITS;
+ default:
+ return ESP_SPIRAM_SIZE_INVALID;
+ }
+}
esp_err_t esp_spiram_init()
{
@@ -138,12 +173,26 @@ esp_err_t esp_spiram_add_to_heapalloc()
static uint8_t *dma_heap;
esp_err_t esp_spiram_reserve_dma_pool(size_t size) {
- if (size==0) return ESP_OK; //no-op
ESP_EARLY_LOGI(TAG, "Reserving pool of %dK of internal memory for DMA/internal allocations", size/1024);
- dma_heap=heap_caps_malloc(size, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
- if (!dma_heap) return ESP_ERR_NO_MEM;
- uint32_t caps[]={MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT};
- return heap_caps_add_region_with_caps(caps, (intptr_t) dma_heap, (intptr_t) dma_heap+size-1);
+ /* Pool may be allocated in multiple non-contiguous chunks, depending on available RAM */
+ while (size > 0) {
+ size_t next_size = heap_caps_get_largest_free_block(MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
+ next_size = MIN(next_size, size);
+
+ ESP_EARLY_LOGD(TAG, "Allocating block of size %d bytes", next_size);
+ dma_heap = heap_caps_malloc(next_size, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
+ if (!dma_heap || next_size == 0) {
+ return ESP_ERR_NO_MEM;
+ }
+
+ uint32_t caps[] = { MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT };
+ esp_err_t e = heap_caps_add_region_with_caps(caps, (intptr_t) dma_heap, (intptr_t) dma_heap+next_size-1);
+ if (e != ESP_OK) {
+ return e;
+ }
+ size -= next_size;
+ }
+ return ESP_OK;
}
size_t esp_spiram_get_size()
diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c
index ed20375da8..2aa3b422bb 100644
--- a/components/esp32/spiram_psram.c
+++ b/components/esp32/spiram_psram.c
@@ -40,26 +40,44 @@
#include "soc/rtc.h"
//Commands for PSRAM chip
-#define PSRAM_READ 0x03
-#define PSRAM_FAST_READ 0x0B
-#define PSRAM_FAST_READ_DUMMY 0x3
-#define PSRAM_FAST_READ_QUAD 0xEB
-#define PSRAM_WRITE 0x02
-#define PSRAM_QUAD_WRITE 0x38
-#define PSRAM_ENTER_QMODE 0x35
-#define PSRAM_EXIT_QMODE 0xF5
-#define PSRAM_RESET_EN 0x66
-#define PSRAM_RESET 0x99
-#define PSRAM_SET_BURST_LEN 0xC0
-#define PSRAM_DEVICE_ID 0x9F
+#define PSRAM_READ 0x03
+#define PSRAM_FAST_READ 0x0B
+#define PSRAM_FAST_READ_DUMMY 0x3
+#define PSRAM_FAST_READ_QUAD 0xEB
+#define PSRAM_FAST_READ_QUAD_DUMMY 0x5
+#define PSRAM_WRITE 0x02
+#define PSRAM_QUAD_WRITE 0x38
+#define PSRAM_ENTER_QMODE 0x35
+#define PSRAM_EXIT_QMODE 0xF5
+#define PSRAM_RESET_EN 0x66
+#define PSRAM_RESET 0x99
+#define PSRAM_SET_BURST_LEN 0xC0
+#define PSRAM_DEVICE_ID 0x9F
-#if CONFIG_SPIRAM_TYPE_ESPPSRAM32
+typedef enum {
+ PSRAM_EID_32MBIT_1V8 = 0x20, /*!< psram EID for 32MBit 1.8V */
+ PSRAM_EID_64MBIT_1V8 = 0x26, /*!< psram EID for 64MBit 1.8V */
+ PSRAM_EID_64MBIT_3V3 = 0x46, /*!< psram EID for 64MBit 3.3V */
+} psram_type_t;
-#define PSRAM_MFG_ID_M 0xff
-#define PSRAM_MFG_ID_S 8
-#define PSRAM_MFG_ID_V 0x5d
+typedef enum {
+ PSRAM_CLK_MODE_NORM = 0, /*!< Normal SPI mode */
+ PSRAM_CLK_MODE_DCLK = 1, /*!< Two extra clock cycles after CS is set high level */
+} psram_clk_mode_t;
-#endif
+#define PSRAM_ID_KGD_M 0xff
+#define PSRAM_ID_KGD_S 8
+#define PSRAM_ID_KGD 0x5d
+#define PSRAM_ID_EID_M 0xff
+#define PSRAM_ID_EID_S 16
+
+#define PSRAM_KGD(id) (((id) >> PSRAM_ID_KGD_S) & PSRAM_ID_KGD_M)
+#define PSRAM_EID(id) (((id) >> PSRAM_ID_EID_S) & PSRAM_ID_EID_M)
+#define PSRAM_IS_VALID(id) (PSRAM_KGD(id) == PSRAM_ID_KGD)
+#define PSRAM_IS_1V8(id) ((PSRAM_EID(id) == PSRAM_EID_32MBIT_1V8) || (PSRAM_EID(id) == PSRAM_EID_64MBIT_1V8))
+#define PSRAM_IS_3V3(id) (PSRAM_EID(id) == PSRAM_EID_64MBIT_3V3)
+#define PSRAM_IS_64MBIT(id) ((PSRAM_EID(id) == PSRAM_EID_64MBIT_3V3) || (PSRAM_EID(id) == PSRAM_EID_64MBIT_1V8))
+#define PSRAM_IS_32MBIT(id) (PSRAM_EID(id) == PSRAM_EID_32MBIT_1V8)
// IO-pins for PSRAM. These need to be in the VDD_SIO power domain because all chips we
// currently support are 1.8V parts.
@@ -94,6 +112,8 @@ typedef enum {
} psram_spi_num_t;
static psram_cache_mode_t s_psram_mode = PSRAM_CACHE_MAX;
+static psram_clk_mode_t s_clk_mode = PSRAM_CLK_MODE_DCLK;
+static uint32_t s_psram_id = 0;
/* dummy_len_plus values defined in ROM for SPI flash configuration */
extern uint8_t g_rom_spiflash_dummy_len_plus[];
@@ -280,7 +300,7 @@ static int psram_cmd_config(psram_spi_num_t spi_num, psram_cmd_t* pInData)
return 0;
}
-void psram_cmd_end(int spi_num) {
+static void psram_cmd_end(int spi_num) {
while (READ_PERI_REG(SPI_CMD_REG(spi_num)) & SPI_USR);
WRITE_PERI_REG(SPI_USER_REG(spi_num), backup_usr[spi_num]);
WRITE_PERI_REG(SPI_USER1_REG(spi_num), backup_usr1[spi_num]);
@@ -292,17 +312,19 @@ static void psram_disable_qio_mode(psram_spi_num_t spi_num)
{
psram_cmd_t ps_cmd;
uint32_t cmd_exit_qpi;
- switch (s_psram_mode) {
- case PSRAM_CACHE_F80M_S80M:
- cmd_exit_qpi = PSRAM_EXIT_QMODE;
- ps_cmd.txDataBitLen = 8;
- break;
- case PSRAM_CACHE_F80M_S40M:
- case PSRAM_CACHE_F40M_S40M:
- default:
- cmd_exit_qpi = PSRAM_EXIT_QMODE << 8;
- ps_cmd.txDataBitLen = 16;
- break;
+ cmd_exit_qpi = PSRAM_EXIT_QMODE;
+ ps_cmd.txDataBitLen = 8;
+ if (s_clk_mode == PSRAM_CLK_MODE_DCLK) {
+ switch (s_psram_mode) {
+ case PSRAM_CACHE_F80M_S80M:
+ break;
+ case PSRAM_CACHE_F80M_S40M:
+ case PSRAM_CACHE_F40M_S40M:
+ default:
+ cmd_exit_qpi = PSRAM_EXIT_QMODE << 8;
+ ps_cmd.txDataBitLen = 16;
+ break;
+ }
}
ps_cmd.txData = &cmd_exit_qpi;
ps_cmd.cmd = 0;
@@ -322,29 +344,34 @@ static void psram_read_id(uint32_t* dev_id)
{
psram_spi_num_t spi_num = PSRAM_SPI_1;
psram_disable_qio_mode(spi_num);
- uint32_t addr = (PSRAM_DEVICE_ID << 24) | 0;
- uint32_t dummy_bits = 0;
+ uint32_t dummy_bits = 0 + extra_dummy;
psram_cmd_t ps_cmd;
- switch (s_psram_mode) {
- case PSRAM_CACHE_F80M_S80M:
- dummy_bits = 0 + extra_dummy;
- ps_cmd.cmdBitLen = 0;
- break;
- case PSRAM_CACHE_F80M_S40M:
- case PSRAM_CACHE_F40M_S40M:
- default:
- dummy_bits = 0 + extra_dummy;
- ps_cmd.cmdBitLen = 2; //this two bits is used to delay 2 clock cycle
- break;
+
+ uint32_t addr = 0;
+ ps_cmd.addrBitLen = 3 * 8;
+ ps_cmd.cmd = PSRAM_DEVICE_ID;
+ ps_cmd.cmdBitLen = 8;
+ if (s_clk_mode == PSRAM_CLK_MODE_DCLK) {
+ switch (s_psram_mode) {
+ case PSRAM_CACHE_F80M_S80M:
+ break;
+ case PSRAM_CACHE_F80M_S40M:
+ case PSRAM_CACHE_F40M_S40M:
+ default:
+ ps_cmd.cmdBitLen = 2; //this two bits is used to delay 2 clock cycle
+ ps_cmd.cmd = 0;
+ addr = (PSRAM_DEVICE_ID << 24) | 0;
+ ps_cmd.addrBitLen = 4 * 8;
+ break;
+ }
}
- ps_cmd.cmd = 0;
ps_cmd.addr = &addr;
- ps_cmd.addrBitLen = 4 * 8;
ps_cmd.txDataBitLen = 0;
ps_cmd.txData = NULL;
ps_cmd.rxDataBitLen = 4 * 8;
ps_cmd.rxData = dev_id;
ps_cmd.dummyBitLen = dummy_bits;
+
psram_cmd_config(spi_num, &ps_cmd);
psram_clear_spi_fifo(spi_num);
psram_cmd_recv_start(spi_num, ps_cmd.rxData, ps_cmd.rxDataBitLen / 8, PSRAM_CMD_SPI);
@@ -356,15 +383,18 @@ static esp_err_t IRAM_ATTR psram_enable_qio_mode(psram_spi_num_t spi_num)
{
psram_cmd_t ps_cmd;
uint32_t addr = (PSRAM_ENTER_QMODE << 24) | 0;
- switch (s_psram_mode) {
- case PSRAM_CACHE_F80M_S80M:
- ps_cmd.cmdBitLen = 0;
- break;
- case PSRAM_CACHE_F80M_S40M:
- case PSRAM_CACHE_F40M_S40M:
- default:
- ps_cmd.cmdBitLen = 2;
- break;
+
+ ps_cmd.cmdBitLen = 0;
+ if (s_clk_mode == PSRAM_CLK_MODE_DCLK) {
+ switch (s_psram_mode) {
+ case PSRAM_CACHE_F80M_S80M:
+ break;
+ case PSRAM_CACHE_F80M_S40M:
+ case PSRAM_CACHE_F40M_S40M:
+ default:
+ ps_cmd.cmdBitLen = 2;
+ break;
+ }
}
ps_cmd.cmd = 0;
ps_cmd.addr = &addr;
@@ -491,6 +521,28 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
}
+psram_volt_t psram_get_volt()
+{
+ if (PSRAM_IS_1V8(s_psram_id)) {
+ return PSRAM_VOLT_1V8;
+ } else if (PSRAM_IS_3V3(s_psram_id)) {
+ return PSRAM_VOLT_3V3;
+ } else {
+ return PSRAM_VOLT_MAX;
+ }
+}
+
+psram_size_t psram_get_size()
+{
+ if (PSRAM_IS_32MBIT(s_psram_id)) {
+ return PSRAM_SIZE_32MBITS;
+ } else if (PSRAM_IS_64MBIT(s_psram_id)) {
+ return PSRAM_SIZE_64MBITS;
+ } else {
+ return PSRAM_SIZE_MAX;
+ }
+}
+
//psram gpio init , different working frequency we have different solutions
esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode) //psram init
{
@@ -507,17 +559,6 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
return ESP_FAIL;
}
- /* note: If the third mode(80Mhz+80Mhz) is enabled, VSPI port will be occupied by the system,
- Application code should never touch VSPI hardware in this case. We try to stop applications
- from doing this using the drivers by claiming the port for ourselves*/
- if (mode == PSRAM_CACHE_F80M_S80M) {
- periph_module_enable(PERIPH_VSPI_MODULE);
- bool r=spicommon_periph_claim(VSPI_HOST);
- if (!r) {
- return ESP_ERR_INVALID_STATE;
- }
- }
-
WRITE_PERI_REG(GPIO_ENABLE_W1TC_REG, BIT(PSRAM_CLK_IO) | BIT(PSRAM_CS_IO)); //DISABLE OUPUT FOR IO16/17
assert(mode < PSRAM_CACHE_MAX && "we don't support any other mode for now.");
s_psram_mode = mode;
@@ -532,21 +573,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
psram_spi_init(PSRAM_SPI_1, mode);
CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_CS_HOLD);
gpio_matrix_out(PSRAM_CS_IO, SPICS1_OUT_IDX, 0, 0);
- gpio_matrix_out(PSRAM_CLK_IO, VSPICLK_OUT_IDX, 0, 0);
- //use spi3 clock,but use spi1 data/cs wires
- //We get a solid 80MHz clock from SPI3 by setting it up, starting a transaction, waiting until it
- //is in progress, then cutting the clock (but not the reset!) to that peripheral.
- WRITE_PERI_REG(SPI_ADDR_REG(PSRAM_SPI_3), 32 << 24);
- WRITE_PERI_REG(SPI_CLOCK_REG(PSRAM_SPI_3), SPI_CLK_EQU_SYSCLK_M); //SET 80M AND CLEAR OTHERS
- SET_PERI_REG_MASK(SPI_CMD_REG(PSRAM_SPI_3), SPI_FLASH_READ_M);
- uint32_t spi_status;
- while (1) {
- spi_status = READ_PERI_REG(SPI_EXT2_REG(PSRAM_SPI_3));
- if (spi_status != 0 && spi_status != 1) {
- DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN);
- break;
- }
- }
+ gpio_matrix_out(PSRAM_CLK_IO, SPICLK_OUT_IDX, 0, 0);
break;
case PSRAM_CACHE_F80M_S40M:
case PSRAM_CACHE_F40M_S40M:
@@ -585,27 +612,58 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CS_IO], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], PIN_FUNC_GPIO);
- uint32_t flash_id = g_rom_flashchip.device_id;
- if (flash_id == FLASH_ID_GD25LQ32C) {
- #if CONFIG_SPIRAM_TYPE_ESPPSRAM32
- // Set drive ability for 1.8v flash in 80Mhz.
- SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV, 3, FUN_DRV_S);
- SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV, 3, FUN_DRV_S);
- SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV, 3, FUN_DRV_S);
- SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV, 3, FUN_DRV_S);
- SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S);
- SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
- SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CS_IO], FUN_DRV, 3, FUN_DRV_S);
- SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 3, FUN_DRV_S);
- #endif
- }
- uint32_t id;
- psram_read_id(&id);
- if (((id >> PSRAM_MFG_ID_S) & PSRAM_MFG_ID_M) != PSRAM_MFG_ID_V) {
+ psram_read_id(&s_psram_id);
+ if (!PSRAM_IS_VALID(s_psram_id)) {
return ESP_FAIL;
}
+ uint32_t flash_id = g_rom_flashchip.device_id;
+ if (flash_id == FLASH_ID_GD25LQ32C && PSRAM_IS_1V8(s_psram_id)) {
+ // Set drive ability for 1.8v flash in 80Mhz.
+ SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV_V, 3, FUN_DRV_S);
+ SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV_V, 3, FUN_DRV_S);
+ SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV_V, 3, FUN_DRV_S);
+ SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV_V, 3, FUN_DRV_S);
+ SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV_V, 3, FUN_DRV_S);
+ SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV_V, 3, FUN_DRV_S);
+ SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CS_IO], FUN_DRV_V, 3, FUN_DRV_S);
+ SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV_V, 3, FUN_DRV_S);
+ }
+ if (PSRAM_EID(s_psram_id) == PSRAM_EID_64MBIT_1V8) {
+ // For this psram, we don't need any extra clock cycles after cs get back to high level
+ s_clk_mode = PSRAM_CLK_MODE_NORM;
+ gpio_matrix_out(PSRAM_INTERNAL_IO_28, SIG_GPIO_OUT_IDX, 0, 0);
+ gpio_matrix_out(PSRAM_INTERNAL_IO_29, SIG_GPIO_OUT_IDX, 0, 0);
+ gpio_matrix_out(PSRAM_CLK_IO, SPICLK_OUT_IDX, 0, 0);
+ } else if (PSRAM_EID(s_psram_id) == PSRAM_EID_32MBIT_1V8 || PSRAM_EID(s_psram_id) == PSRAM_EID_64MBIT_3V3) {
+ s_clk_mode = PSRAM_CLK_MODE_DCLK;
+ if (mode == PSRAM_CACHE_F80M_S80M) {
+ /* note: If the third mode(80Mhz+80Mhz) is enabled for 32MBit 1V8 psram and 64MBit 3.3v psram,
+ VSPI port will be occupied by the system.
+ Application code should never touch VSPI hardware in this case. We try to stop applications
+ from doing this using the drivers by claiming the port for ourselves*/
+ periph_module_enable(PERIPH_VSPI_MODULE);
+ bool r=spicommon_periph_claim(VSPI_HOST);
+ if (!r) {
+ return ESP_ERR_INVALID_STATE;
+ }
+ gpio_matrix_out(PSRAM_CLK_IO, VSPICLK_OUT_IDX, 0, 0);
+ //use spi3 clock,but use spi1 data/cs wires
+ //We get a solid 80MHz clock from SPI3 by setting it up, starting a transaction, waiting until it
+ //is in progress, then cutting the clock (but not the reset!) to that peripheral.
+ WRITE_PERI_REG(SPI_ADDR_REG(PSRAM_SPI_3), 32 << 24);
+ WRITE_PERI_REG(SPI_CLOCK_REG(PSRAM_SPI_3), SPI_CLK_EQU_SYSCLK_M); //SET 80M AND CLEAR OTHERS
+ SET_PERI_REG_MASK(SPI_CMD_REG(PSRAM_SPI_3), SPI_FLASH_READ_M);
+ uint32_t spi_status;
+ while (1) {
+ spi_status = READ_PERI_REG(SPI_EXT2_REG(PSRAM_SPI_3));
+ if (spi_status != 0 && spi_status != 1) {
+ DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN);
+ break;
+ }
+ }
+ }
+ }
psram_enable_qio_mode(PSRAM_SPI_1);
-
psram_cache_init(mode, vaddrmode);
return ESP_OK;
}
@@ -624,27 +682,15 @@ static void IRAM_ATTR psram_cache_init(psram_cache_mode_t psram_cache_mode, psra
CLEAR_PERI_REG_MASK(SPI_DATE_REG(0), BIT(31)); //flash 1 div clk,80+40;
CLEAR_PERI_REG_MASK(SPI_DATE_REG(0), BIT(30)); //pre clk div , ONLY IF SPI/SRAM@ DIFFERENT SPEED,JUST FOR SPI0. FLASH DIV 2+SRAM DIV4
WRITE_PERI_REG(SPI_CLOCK_REG(0), SPI_CLK_EQU_SYSCLK_M); //SET 1DIV CLOCK AND RESET OTHER PARAMS
- SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_RD_SRAM_DUMMY_M); //enable cache read dummy
- SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_DUMMY_CYCLELEN_V, PSRAM_FAST_READ_DUMMY + extra_dummy,
- SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy,80m--+2dummy
- SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_RCMD_M); //enable user mode for cache read command
break;
case PSRAM_CACHE_F80M_S40M:
SET_PERI_REG_MASK(SPI_DATE_REG(0), BIT(31)); //flash 1 div clk
CLEAR_PERI_REG_MASK(SPI_DATE_REG(0), BIT(30)); //pre clk div , ONLY IF SPI/SRAM@ DIFFERENT SPEED,JUST FOR SPI0.
- SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_RD_SRAM_DUMMY_M); //enable cache read dummy
- SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_DUMMY_CYCLELEN_V, PSRAM_FAST_READ_DUMMY + extra_dummy,
- SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy,80m--+2dummy
- SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_RCMD_M); //enable user mode for cache read command
break;
case PSRAM_CACHE_F40M_S40M:
default:
CLEAR_PERI_REG_MASK(SPI_DATE_REG(0), BIT(31)); //flash 1 div clk
CLEAR_PERI_REG_MASK(SPI_DATE_REG(0), BIT(30)); //pre clk div
- SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_RD_SRAM_DUMMY_M); //enable cache read dummy
- SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_DUMMY_CYCLELEN_V, PSRAM_FAST_READ_DUMMY + extra_dummy,
- SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy,80m--+2dummy
- SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_RCMD_M); //enable user mode for cache read command
break;
}
SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_WCMD_M); // cache write command enable
@@ -652,30 +698,38 @@ static void IRAM_ATTR psram_cache_init(psram_cache_mode_t psram_cache_mode, psra
SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_SRAM_QIO_M); //enable qio mode for cache command
CLEAR_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_SRAM_DIO_M); //disable dio mode for cache command
+ SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_USR_RD_SRAM_DUMMY_M); //enable cache read dummy
+ SET_PERI_REG_MASK(SPI_CACHE_SCTRL_REG(0), SPI_CACHE_SRAM_USR_RCMD_M); //enable user mode for cache read command
+ SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_BITLEN, 7,
+ SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S);
+ SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_VALUE, PSRAM_QUAD_WRITE,
+ SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S); //0x38
+ SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 7,
+ SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S);
+ SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V, PSRAM_FAST_READ_QUAD,
+ SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0x0b
+ SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_DUMMY_CYCLELEN_V, PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy,
+ SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy,80m--+2dummy
//config sram cache r/w command
switch (psram_cache_mode) {
case PSRAM_CACHE_F80M_S80M: //in this mode , no delay is needed
- SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_BITLEN, 7,
- SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S);
- SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_VALUE, PSRAM_QUAD_WRITE,
- SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S); //0x38
- SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 7,
- SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S);
- SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V, PSRAM_FAST_READ,
- SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0x0b
break;
case PSRAM_CACHE_F80M_S40M: //is sram is @40M, need 2 cycles of delay
case PSRAM_CACHE_F40M_S40M:
default:
- SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 15,
- SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S); //read command length, 2 bytes(1byte for delay),sending in qio mode in cache
- SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V, ((PSRAM_FAST_READ) << 8),
- SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0x0b, read command value,(0x00 for delay,0x0b for cmd)
- SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_BITLEN, 15,
- SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S); //write command length,2 bytes(1byte for delay,send in qio mode in cache)
- SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_VALUE, ((PSRAM_QUAD_WRITE) << 8),
- SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S); //0x38, write command value,(0x00 for delay)
+ if (s_clk_mode == PSRAM_CLK_MODE_DCLK) {
+ SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 15,
+ SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S); //read command length, 2 bytes(1byte for delay),sending in qio mode in cache
+ SET_PERI_REG_BITS(SPI_SRAM_DRD_CMD_REG(0), SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V, ((PSRAM_FAST_READ_QUAD) << 8),
+ SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0x0b, read command value,(0x00 for delay,0x0b for cmd)
+ SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_BITLEN, 15,
+ SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S); //write command length,2 bytes(1byte for delay,send in qio mode in cache)
+ SET_PERI_REG_BITS(SPI_SRAM_DWR_CMD_REG(0), SPI_CACHE_SRAM_USR_WR_CMD_VALUE, ((PSRAM_QUAD_WRITE) << 8),
+ SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S); //0x38, write command value,(0x00 for delay)
+ SET_PERI_REG_BITS(SPI_CACHE_SCTRL_REG(0), SPI_SRAM_DUMMY_CYCLELEN_V, PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy,
+ SPI_SRAM_DUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy,80m--+2dummy
+ }
break;
}
@@ -698,6 +752,11 @@ static void IRAM_ATTR psram_cache_init(psram_cache_mode_t psram_cache_mode, psra
CLEAR_PERI_REG_MASK(SPI_PIN_REG(0), SPI_CS1_DIS_M); //ENABLE SPI0 CS1 TO PSRAM(CS0--FLASH; CS1--SRAM)
+ if (s_clk_mode == PSRAM_CLK_MODE_NORM) { //different
+ SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_CS_HOLD);
+ // Set cs time.
+ SET_PERI_REG_BITS(SPI_CTRL2_REG(0), SPI_SETUP_TIME_V, 1, SPI_SETUP_TIME_S);
+ }
}
#endif // CONFIG_SPIRAM_SUPPORT
diff --git a/components/esp32/spiram_psram.h b/components/esp32/spiram_psram.h
index 10de4e1d6c..1756eed73d 100644
--- a/components/esp32/spiram_psram.h
+++ b/components/esp32/spiram_psram.h
@@ -26,6 +26,17 @@ typedef enum {
PSRAM_CACHE_MAX,
} psram_cache_mode_t;
+typedef enum {
+ PSRAM_VOLT_3V3 = 0,
+ PSRAM_VOLT_1V8 = 1,
+ PSRAM_VOLT_MAX,
+} psram_volt_t;
+
+typedef enum {
+ PSRAM_SIZE_32MBITS = 0,
+ PSRAM_SIZE_64MBITS = 1,
+ PSRAM_SIZE_MAX,
+} psram_size_t;
/*
See the TRM, chapter PID/MPU/MMU, header 'External RAM' for the definitions of these modes.
@@ -34,12 +45,29 @@ Important is that NORMAL works with the app CPU cache disabled, but gives huge c
issues when both app and pro CPU are enabled. LOWHIGH and EVENODD do not have these coherency
issues but cannot be used when the app CPU cache is disabled.
*/
+
typedef enum {
PSRAM_VADDR_MODE_NORMAL=0, ///< App and pro CPU use their own flash cache for external RAM access
PSRAM_VADDR_MODE_LOWHIGH, ///< App and pro CPU share external RAM caches: pro CPU has low 2M, app CPU has high 2M
PSRAM_VADDR_MODE_EVENODD, ///< App and pro CPU share external RAM caches: pro CPU does even 32yte ranges, app does odd ones.
} psram_vaddr_mode_t;
+/**
+ * @brief get psram voltage
+ * @return
+ * - PSRAM_VOLT_MAX if psram not enabled or not valid.
+ * - PSRAM voltage
+ */
+psram_volt_t psram_get_volt();
+
+/**
+ * @brief get psram size
+ * @return
+ * - PSRAM_SIZE_MAX if psram not enabled or not valid
+ * - PSRAM size
+ */
+psram_size_t psram_get_size();
+
/**
* @brief psram cache enable function
*
diff --git a/components/esp32/system_api.c b/components/esp32/system_api.c
index 8068f3bc4f..f56bf622e2 100644
--- a/components/esp32/system_api.c
+++ b/components/esp32/system_api.c
@@ -31,6 +31,7 @@
#include "soc/timer_group_struct.h"
#include "soc/cpu.h"
#include "soc/rtc.h"
+#include "soc/rtc_wdt.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/xtensa_api.h"
@@ -270,14 +271,15 @@ void IRAM_ATTR esp_restart_noos()
xt_ints_off(0xFFFFFFFF);
// Enable RTC watchdog for 1 second
- REG_WRITE(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
- REG_WRITE(RTC_CNTL_WDTCONFIG0_REG,
- RTC_CNTL_WDT_FLASHBOOT_MOD_EN_M |
- (RTC_WDT_STG_SEL_RESET_SYSTEM << RTC_CNTL_WDT_STG0_S) |
- (RTC_WDT_STG_SEL_RESET_RTC << RTC_CNTL_WDT_STG1_S) |
- (1 << RTC_CNTL_WDT_SYS_RESET_LENGTH_S) |
- (1 << RTC_CNTL_WDT_CPU_RESET_LENGTH_S) );
- REG_WRITE(RTC_CNTL_WDTCONFIG1_REG, rtc_clk_slow_freq_get_hz() * 1);
+ rtc_wdt_protect_off();
+ rtc_wdt_disable();
+ rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_RTC);
+ rtc_wdt_set_stage(RTC_WDT_STAGE1, RTC_WDT_STAGE_ACTION_RESET_SYSTEM);
+ rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_200ns);
+ rtc_wdt_set_length_of_reset_signal(RTC_WDT_CPU_RESET_SIG, RTC_WDT_LENGTH_200ns);
+ rtc_wdt_set_time(RTC_WDT_STAGE0, 1000);
+ rtc_wdt_enable();
+ rtc_wdt_protect_on();
// Reset and stall the other CPU.
// CPU must be reset before stalling, in case it was running a s32c1i
diff --git a/components/esp32/test/component.mk b/components/esp32/test/component.mk
index 178dd4cf4d..592b9b9048 100644
--- a/components/esp32/test/component.mk
+++ b/components/esp32/test/component.mk
@@ -12,6 +12,11 @@ COMPONENT_SRCDIRS := . test_vectors
WIFI_OS_ADAPTER_MD5_VAL=\"$(shell md5sum $(IDF_PATH)/components/esp32/include/esp_wifi_os_adapter.h | cut -c 1-7)\"
CFLAGS+=-DWIFI_OS_ADAPTER_MD5=$(WIFI_OS_ADAPTER_MD5_VAL)
+# Calculate MD5 value of header file esp_wifi_crypto_types.h
+WIFI_CRYPTO_MD5_VAL=\"$(shell md5sum $(IDF_PATH)/components/esp32/include/esp_wifi_crypto_types.h | cut -c 1-7)\"
+CFLAGS+=-DWIFI_CRYPTO_MD5=$(WIFI_CRYPTO_MD5_VAL)
+
+
test_tjpgd.o: test_tjpgd_logo.h
test_tjpgd_logo.h: $(COMPONENT_PATH)/logo.jpg
diff --git a/components/esp32/test/test_esp32.c b/components/esp32/test/test_esp32.c
index 0681660ff1..cdca805df4 100644
--- a/components/esp32/test/test_esp32.c
+++ b/components/esp32/test/test_esp32.c
@@ -83,8 +83,8 @@ TEST_CASE("wifi stop and deinit","[wifi]")
//init nvs
ESP_LOGI(TAG, EMPH_STR("nvs_flash_init"));
esp_err_t r = nvs_flash_init();
- if (r == ESP_ERR_NVS_NO_FREE_PAGES) {
- ESP_LOGI(TAG, EMPH_STR("no free pages, erase.."));
+ if (r == ESP_ERR_NVS_NO_FREE_PAGES || r == ESP_ERR_NVS_NEW_VERSION_FOUND) {
+ ESP_LOGI(TAG, EMPH_STR("no free pages or nvs version mismatch, erase.."));
TEST_ESP_OK(nvs_flash_erase());
r = nvs_flash_init();
}
diff --git a/components/esp32/test/test_esp_timer.c b/components/esp32/test/test_esp_timer.c
index da8d8951cf..3b6f3b40d6 100644
--- a/components/esp32/test/test_esp_timer.c
+++ b/components/esp32/test/test_esp_timer.c
@@ -2,6 +2,7 @@
#include
#include
#include
+#include
#include "unity.h"
#include "esp_timer.h"
#include "esp_heap_caps.h"
@@ -15,6 +16,20 @@
#define WITH_PROFILING 1
#endif
+extern uint32_t esp_timer_impl_get_overflow_val();
+extern void esp_timer_impl_set_overflow_val(uint32_t overflow_val);
+
+static uint32_t s_old_overflow_val;
+
+static void setup_overflow()
+{
+ s_old_overflow_val = esp_timer_impl_get_overflow_val();
+ esp_timer_impl_set_overflow_val(0x7fffff); /* overflow every ~0.1 sec */}
+
+static void teardown_overflow()
+{
+ esp_timer_impl_set_overflow_val(s_old_overflow_val);
+}
TEST_CASE("esp_timer orders timers correctly", "[esp_timer]")
{
@@ -27,6 +42,7 @@ TEST_CASE("esp_timer orders timers correctly", "[esp_timer]")
const size_t num_timers = sizeof(timeouts)/sizeof(timeouts[0]);
esp_timer_handle_t handles[num_timers];
char* names[num_timers];
+ setup_overflow();
for (size_t i = 0; i < num_timers; ++i) {
asprintf(&names[i], "timer%d", i);
esp_timer_create_args_t args = {
@@ -36,6 +52,7 @@ TEST_CASE("esp_timer orders timers correctly", "[esp_timer]")
TEST_ESP_OK(esp_timer_create(&args, &handles[i]));
TEST_ESP_OK(esp_timer_start_once(handles[i], timeouts[i] * 100));
}
+ teardown_overflow();
char* stream_str[1024];
FILE* stream = fmemopen(stream_str, sizeof(stream_str), "r+");
TEST_ESP_OK(esp_timer_dump(stream));
@@ -68,6 +85,42 @@ TEST_CASE("esp_timer orders timers correctly", "[esp_timer]")
fclose(stream);
}
+TEST_CASE("esp_timer_impl_set_alarm stress test", "[esp_timer]")
+{
+ const int test_time_sec = 10;
+
+ void set_alarm_task(void* arg)
+ {
+ SemaphoreHandle_t done = (SemaphoreHandle_t) arg;
+
+ uint64_t start = esp_timer_impl_get_time();
+ uint64_t now = start;
+ int count = 0;
+ const int delays[] = {50, 5000, 10000000};
+ const int delays_count = sizeof(delays)/sizeof(delays[0]);
+ while (now - start < test_time_sec * 1000000) {
+ now = esp_timer_impl_get_time();
+ esp_timer_impl_set_alarm(now + delays[count % delays_count]);
+ ++count;
+ }
+ xSemaphoreGive(done);
+ vTaskDelete(NULL);
+ }
+
+ SemaphoreHandle_t done = xSemaphoreCreateCounting(portNUM_PROCESSORS, 0);
+ setup_overflow();
+ xTaskCreatePinnedToCore(&set_alarm_task, "set_alarm_0", 4096, done, UNITY_FREERTOS_PRIORITY, NULL, 0);
+#if portNUM_PROCESSORS == 2
+ xTaskCreatePinnedToCore(&set_alarm_task, "set_alarm_1", 4096, done, UNITY_FREERTOS_PRIORITY, NULL, 1);
+#endif
+
+ TEST_ASSERT(xSemaphoreTake(done, test_time_sec * 2 * 1000 / portTICK_PERIOD_MS));
+#if portNUM_PROCESSORS == 2
+ TEST_ASSERT(xSemaphoreTake(done, test_time_sec * 2 * 1000 / portTICK_PERIOD_MS));
+#endif
+ teardown_overflow();
+ vSemaphoreDelete(done);
+}
TEST_CASE("esp_timer produces correct delay", "[esp_timer]")
{
@@ -90,6 +143,7 @@ TEST_CASE("esp_timer produces correct delay", "[esp_timer]")
const size_t delays_count = sizeof(delays_ms)/sizeof(delays_ms[0]);
ref_clock_init();
+ setup_overflow();
for (size_t i = 0; i < delays_count; ++i) {
t_end = 0;
int64_t t_start = ref_clock_get();
@@ -103,6 +157,7 @@ TEST_CASE("esp_timer produces correct delay", "[esp_timer]")
TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, delays_ms[i], ms_diff);
}
+ teardown_overflow();
ref_clock_deinit();
TEST_ESP_OK( esp_timer_dump(stdout) );
@@ -150,6 +205,7 @@ TEST_CASE("periodic esp_timer produces correct delays", "[esp_timer]")
};
TEST_ESP_OK(esp_timer_create(&create_args, &timer1));
ref_clock_init();
+ setup_overflow();
args.timer = timer1;
args.t_start = ref_clock_get();
args.done = xSemaphoreCreateBinary();
@@ -161,6 +217,7 @@ TEST_CASE("periodic esp_timer produces correct delays", "[esp_timer]")
for (size_t i = 0; i < NUM_INTERVALS; ++i) {
TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, (i + 1) * delay_ms, args.intervals[i]);
}
+ teardown_overflow();
ref_clock_deinit();
TEST_ESP_OK( esp_timer_dump(stdout) );
@@ -317,6 +374,7 @@ TEST_CASE("esp_timer for very short intervals", "[esp_timer]")
esp_timer_handle_t timer1, timer2;
ESP_ERROR_CHECK( esp_timer_create(&timer_args, &timer1) );
ESP_ERROR_CHECK( esp_timer_create(&timer_args, &timer2) );
+ setup_overflow();
const int timeout_ms = 10;
for (int timeout_delta_us = -150; timeout_delta_us < 150; timeout_delta_us++) {
printf("delta=%d", timeout_delta_us);
@@ -329,6 +387,7 @@ TEST_CASE("esp_timer for very short intervals", "[esp_timer]")
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_timer_stop(timer2));
}
+ teardown_overflow();
vSemaphoreDelete(semaphore);
}
@@ -345,40 +404,75 @@ TEST_CASE("esp_timer_get_time call takes less than 1us", "[esp_timer]")
TEST_PERFORMANCE_LESS_THAN(ESP_TIMER_GET_TIME_PER_CALL, "%dns", ns_per_call);
}
-/* This test runs for about 10 minutes and is disabled in CI.
- * Such run time is needed to have FRC2 timer overflow a few times.
- */
-TEST_CASE("esp_timer_get_time returns monotonic values", "[esp_timer][ignore]")
+TEST_CASE("esp_timer_get_time returns monotonic values", "[esp_timer]")
{
- void timer_test_task(void* arg) {
- int64_t delta = esp_timer_get_time() - ref_clock_get();
+ typedef struct {
+ SemaphoreHandle_t done;
+ bool pass;
+ int test_cnt;
+ int error_cnt;
+ int64_t total_sq_error;
+ int64_t max_error;
+ } test_state_t;
- const int iter_count = 1000000000;
- for (int i = 0; i < iter_count; ++i) {
- int64_t now = esp_timer_get_time();
- int64_t ref_now = ref_clock_get();
- int64_t diff = now - (ref_now + delta);
+ void timer_test_task(void* arg) {
+ test_state_t* state = (test_state_t*) arg;
+ state->pass = true;
+ int64_t start_time = ref_clock_get();
+ int64_t delta = esp_timer_get_time() - start_time;
+
+ int64_t now = start_time;
+ int error_repeat_cnt = 0;
+ while (now - start_time < 10000000) { /* 10 seconds */
+ int64_t hs_now = esp_timer_get_time();
+ now = ref_clock_get();
+ int64_t diff = hs_now - (now + delta);
/* Allow some difference due to rtos tick interrupting task between
* getting 'now' and 'ref_now'.
*/
- TEST_ASSERT_INT32_WITHIN(100, 0, (int) diff);
+ if (abs(diff) > 100) {
+ error_repeat_cnt++;
+ state->error_cnt++;
+ } else {
+ error_repeat_cnt = 0;
+ }
+ if (error_repeat_cnt > 2) {
+ printf("diff=%lld\n", diff);
+ state->pass = false;
+ }
+ state->max_error = MAX(state->max_error, abs(diff));
+ state->test_cnt++;
+ state->total_sq_error += diff * diff;
}
-
- xSemaphoreGive((SemaphoreHandle_t) arg);
+ xSemaphoreGive(state->done);
vTaskDelete(NULL);
}
+
ref_clock_init();
- SemaphoreHandle_t done_1 = xSemaphoreCreateBinary();
- SemaphoreHandle_t done_2 = xSemaphoreCreateBinary();
+ setup_overflow();
- xTaskCreatePinnedToCore(&timer_test_task, "t1", 4096, (void*) done_1, 6, NULL, 0);
- xTaskCreatePinnedToCore(&timer_test_task, "t2", 4096, (void*) done_2, 6, NULL, 1);
+ test_state_t states[portNUM_PROCESSORS] = {0};
+ SemaphoreHandle_t done = xSemaphoreCreateCounting(portNUM_PROCESSORS, 0);
+ for (int i = 0; i < portNUM_PROCESSORS; ++i) {
+ states[i].done = done;
+ xTaskCreatePinnedToCore(&timer_test_task, "test", 4096, &states[i], 6, NULL, i);
+ }
- TEST_ASSERT_TRUE( xSemaphoreTake(done_1, portMAX_DELAY) );
- TEST_ASSERT_TRUE( xSemaphoreTake(done_2, portMAX_DELAY) );
- vSemaphoreDelete(done_1);
- vSemaphoreDelete(done_2);
+ for (int i = 0; i < portNUM_PROCESSORS; ++i) {
+ TEST_ASSERT_TRUE( xSemaphoreTake(done, portMAX_DELAY) );
+ printf("CPU%d: %s test_cnt=%d error_cnt=%d std_error=%d |max_error|=%d\n",
+ i, states[i].pass ? "PASS" : "FAIL",
+ states[i].test_cnt, states[i].error_cnt,
+ (int) sqrt(states[i].total_sq_error / states[i].test_cnt), (int) states[i].max_error);
+ }
+
+ vSemaphoreDelete(done);
+ teardown_overflow();
ref_clock_deinit();
+
+ for (int i = 0; i < portNUM_PROCESSORS; ++i) {
+ TEST_ASSERT(states[i].pass);
+ }
}
TEST_CASE("Can dump esp_timer stats", "[esp_timer]")
diff --git a/components/esp32/test/test_os_adapter_md5.c b/components/esp32/test/test_header_files_md5.c
similarity index 52%
rename from components/esp32/test/test_os_adapter_md5.c
rename to components/esp32/test/test_header_files_md5.c
index 315a386081..009de0ea59 100644
--- a/components/esp32/test/test_os_adapter_md5.c
+++ b/components/esp32/test/test_header_files_md5.c
@@ -5,7 +5,7 @@
#include "esp_log.h"
#include "esp_wifi_internal.h"
-static const char* TAG = "test_os_adapter_md5";
+static const char* TAG = "test_header_files_md5";
TEST_CASE("wifi os adapter MD5","[wifi]")
{
@@ -16,3 +16,13 @@ TEST_CASE("wifi os adapter MD5","[wifi]")
ESP_LOGI(TAG, "test passed...");
}
+
+TEST_CASE("wifi crypto types MD5","[wifi]")
+{
+ const char *test_wifi_crypto_funcs_md5 = WIFI_CRYPTO_MD5;
+
+ ESP_LOGI(TAG, "test wifi crypto adapter MD5...");
+ TEST_ESP_OK(esp_wifi_internal_crypto_funcs_md5_check(test_wifi_crypto_funcs_md5));
+
+ ESP_LOGI(TAG, "test passed...");
+}
diff --git a/components/esp32/test/test_intr_alloc.c b/components/esp32/test/test_intr_alloc.c
index 00a325b1ea..0112814fa7 100644
--- a/components/esp32/test/test_intr_alloc.c
+++ b/components/esp32/test/test_intr_alloc.c
@@ -231,7 +231,7 @@ TEST_CASE("Can allocate IRAM int only with an IRAM handler", "[esp32]")
}
-#include "soc/spi_struct.h"
+#include "soc/spi_periph.h"
typedef struct {
bool flag1;
bool flag2;
diff --git a/components/esp32/test/test_libgcc.c b/components/esp32/test/test_libgcc.c
new file mode 100644
index 0000000000..7fca990d48
--- /dev/null
+++ b/components/esp32/test/test_libgcc.c
@@ -0,0 +1,185 @@
+#include
+#include "unity.h"
+
+TEST_CASE("libgcc math functions", "[rom]")
+{
+ extern int64_t __absvdi2(int64_t x);
+ TEST_ASSERT(__absvdi2(-1L) == 1);
+ extern int __absvsi2(int x);
+ TEST_ASSERT(__absvsi2(-1) == 1);
+ extern double __adddf3(double x, double y);
+ TEST_ASSERT(__adddf3(1.0, 4.0) == 5.0);
+ extern float __addsf3(float x, float y);
+ TEST_ASSERT(__addsf3(1.0f, 4.0f) == 5.0f);
+ extern int64_t __addvdi3(int64_t x, int64_t y);
+ TEST_ASSERT(__addvdi3(1L, 4L) == 5L);
+ extern int __addvsi3(int x, int y);
+ TEST_ASSERT(__addvsi3(1, 4) == 5);
+ extern int64_t __ashldi3(int64_t x, int y);
+ TEST_ASSERT(__ashldi3(1, 4) == 16);
+ extern int64_t __ashrdi3(int64_t x, int y);
+ TEST_ASSERT(__ashrdi3(4, 1) == 2);
+ extern int64_t __bswapdi2(int64_t x);
+ TEST_ASSERT(__bswapdi2(0xaabbccddeeff0011ULL) == 0x1100ffeeddccbbaaULL);
+ extern int32_t __bswapsi2(int32_t x);
+ TEST_ASSERT(__bswapsi2(0xaabbccdd) == 0xddccbbaa);
+ extern int64_t __clrsbdi2(int64_t x);
+ TEST_ASSERT(__clrsbdi2(-1) == 63);
+ extern int __clrsbsi2(int x);
+ TEST_ASSERT(__clrsbsi2(-1) == 31);
+ extern int __clzdi2(int64_t x);
+ TEST_ASSERT(__clzdi2(1) == 63);
+ extern int __clzsi2(int x);
+ TEST_ASSERT(__clzsi2(1) == 31);
+ extern int __cmpdi2(int64_t x, int64_t y);
+ TEST_ASSERT(__cmpdi2(10, 10) == 1);
+ extern int __ctzdi2(uint64_t x);
+ TEST_ASSERT(__ctzdi2(0x8000000000000000ULL) == 63);
+ extern int __ctzsi2(unsigned x);
+ TEST_ASSERT(__ctzsi2(0x80000000U) == 31);
+ extern complex double __divdc3(double a, double b, double c, double d);
+ TEST_ASSERT(__divdc3(0, 1, 1, 0) == I);
+ extern double __divdf3(double x, double y);
+ TEST_ASSERT(__divdf3(16.0, 2.0) == 8.0);
+ extern int64_t __divdi3(int64_t x, int64_t y);
+ TEST_ASSERT(__divdi3(16, 2) == 8);
+ extern complex float __divsc3(float a, float b, float c, float d);
+ TEST_ASSERT(__divsc3(0, 1, 1, 0) == I);
+ extern float __divsf3(float x, float y);
+ TEST_ASSERT(__divsf3(16.0f, 2.0f) == 8.0f);
+ extern int __divsi3(int x, int y);
+ TEST_ASSERT(__divsi3(16, 2) == 8);
+ extern int __eqdf2(double x, double y);
+ TEST_ASSERT(__eqdf2(4.0, 4.0) == 0);
+ extern int __eqsf2(float x, float y);
+ TEST_ASSERT(__eqsf2(4.0f, 4.0f) == 0);
+ extern double __extendsfdf2(float x);
+ TEST_ASSERT(__extendsfdf2(4.0f) == 4.0);
+ extern int __ffsdi2(uint64_t x);
+ TEST_ASSERT(__ffsdi2(0x8000000000000000ULL) == 64);
+ extern int __ffssi2(unsigned x);
+ TEST_ASSERT(__ffssi2(0x80000000) == 32);
+ extern int64_t __fixdfdi(double x);
+ TEST_ASSERT(__fixdfdi(4.0) == 4LL);
+ extern int __fixdfsi(double x);
+ TEST_ASSERT(__fixdfsi(4.0) == 4);
+ extern int64_t __fixsfdi(float x);
+ TEST_ASSERT(__fixsfdi(4.0f) == 4LL);
+ extern int __fixsfsi(float x);
+ TEST_ASSERT(__fixsfsi(4.0f) == 4);
+ extern unsigned __fixunsdfsi(double x);
+ TEST_ASSERT(__fixunsdfsi(16.0) == 16);
+ extern uint64_t __fixunssfdi(float x);
+ TEST_ASSERT(__fixunssfdi(16.0f) == 16);
+ extern unsigned __fixunssfsi(float x);
+ TEST_ASSERT(__fixunssfsi(16.0f) == 16);
+ extern double __floatdidf(int64_t);
+ TEST_ASSERT(__floatdidf(-1LL) == -1.0f);
+ extern float __floatdisf(int64_t);
+ TEST_ASSERT(__floatdisf(-1LL) == -1.0f);
+ extern double __floatsidf(int x);
+ TEST_ASSERT(__floatsidf(-1) == -1.0);
+ extern float __floatsisf(int x);
+ TEST_ASSERT(__floatsisf(-1) == -1.0f);
+ extern double __floatundidf(uint64_t x);
+ TEST_ASSERT(__floatundidf(16) == 16.0);
+ extern float __floatundisf(uint64_t x);
+ TEST_ASSERT(__floatundisf(16) == 16.0f);
+ extern double __floatunsidf(unsigned x);
+ TEST_ASSERT(__floatunsidf(16) == 16.0);
+ extern float __floatunsisf(unsigned x);
+ TEST_ASSERT(__floatunsisf(16) == 16.0f);
+ extern int __gedf2(double x, double y);
+ TEST_ASSERT(__gedf2(2.0, 0.0) >= 0);
+ extern int __gesf2(float x, float y);
+ TEST_ASSERT(__gesf2(2.0f, 0.0f) >= 0);
+ extern int __gtdf2(double x, double y);
+ TEST_ASSERT(__gtdf2(2.0, 0.0) >= 0);
+ extern int __gtsf2(float x, float y);
+ TEST_ASSERT(__gtsf2(2.0f, 0.0f) >= 0);
+ extern int __ledf2(double x, double y);
+ TEST_ASSERT(__ledf2(0.0, 2.0) <= 0);
+ extern int __lesf2(float x, float y);
+ TEST_ASSERT(__lesf2(0.0f, 2.0f) <= 0);
+ extern int64_t __lshrdi3(int64_t x, int y);
+ TEST_ASSERT(__lshrdi3(0x8000000000000000LL, 1) == 0x4000000000000000LL);
+ extern int __ltdf2(double x, double y);
+ TEST_ASSERT(__ltdf2(0.0, 2.0) < 0);
+ extern int __ltsf2(float x, float y);
+ TEST_ASSERT(__ltsf2(0.0f, 2.0f) < 0);
+ extern int64_t __moddi3(int64_t x, int64_t y);
+ TEST_ASSERT(__moddi3(15, 2) == 1);
+ extern int __modsi3(int x, int y);
+ TEST_ASSERT(__modsi3(15, 2) == 1);
+ extern complex double __muldc3(double a, double b, double c, double d);
+ TEST_ASSERT(__muldc3(1.0, 0.0, 0.0, 1.0) == I);
+ extern double __muldf3(double x, double y);
+ TEST_ASSERT(__muldf3(2.0, 8.0) == 16.0);
+ extern int64_t __muldi3(int64_t x, int64_t y);
+ TEST_ASSERT(__muldi3(2, 8) == 16);
+ extern complex float __mulsc3 (float a, float b, float c, float d);
+ TEST_ASSERT(__mulsc3(1.0f, 0.0f, 0.0f, -1.0f) == -I);
+ extern float __mulsf3 (float a, float b);
+ TEST_ASSERT(__mulsf3(2.0f, 8.0f) == 16.0f);
+ extern int __mulsi3(int x, int y);
+ TEST_ASSERT(__mulsi3(2, 8) == 16);
+ extern int __mulvdi3(int64_t x, int64_t y);
+ TEST_ASSERT(__mulvdi3(2, 8) == 16);
+ extern int __mulvsi3(int x, int y);
+ TEST_ASSERT(__mulvsi3(2, 8) == 16);
+ extern int __nedf2(double x, double y);
+ TEST_ASSERT(__nedf2(2.0, 2.0) == 0);
+ extern double __negdf2(double x);
+ TEST_ASSERT(__negdf2(1.0) == -1.0);
+ extern int64_t __negdi2(int64_t x);
+ TEST_ASSERT(__negdi2(-1LL) == 1);
+ extern float __negsf2(float x);
+ TEST_ASSERT(__negsf2(-1.0f) == 1.0f);
+ extern int64_t __negvdi2(int64_t x);
+ TEST_ASSERT(__negvdi2(-1LL) == 1);
+ extern int __negvsi2(int x);
+ TEST_ASSERT(__negvsi2(-1) == 1);
+ extern int __nesf2(float x, float y);
+ TEST_ASSERT(__nesf2(2.0, 0.0) != 0);
+ extern int __paritysi2(unsigned x);
+ TEST_ASSERT(__paritysi2(0x10101010) == 0);
+ extern int __popcountdi2(uint64_t);
+ TEST_ASSERT(__popcountdi2(0xaaaaaaaa11111111ULL) == 24);
+ extern int __popcountsi2(unsigned x);
+ TEST_ASSERT(__popcountsi2(0x11111111) == 8);
+ extern double __powidf2(double x, int y);
+ TEST_ASSERT(__powidf2(2.0, -1) == 0.5);
+ extern float __powisf2(float x, int y);
+ TEST_ASSERT(__powisf2(2.0f, 2) == 4.0f);
+ extern double __subdf3(double x, double y);
+ TEST_ASSERT(__subdf3(2.0, 1.0) == 1.0);
+ extern float __subsf3(float x, float y);
+ TEST_ASSERT(__subsf3(5.0f, 4.0f) == 1.0f);
+ extern int64_t __subvdi3(int64_t x, int64_t y);
+ TEST_ASSERT(__subvdi3(-1LL, -1LL) == 0);
+ extern int __subvsi3(int x, int y);
+ TEST_ASSERT(__subvsi3(-1, -1) == 0);
+ extern float __truncdfsf2(double x);
+ TEST_ASSERT(__truncdfsf2(4.0) == 4.0f);
+ extern int __ucmpdi2(uint64_t x, uint64_t y);
+ TEST_ASSERT(__ucmpdi2(0x100000000ULL, 0x100000000ULL) == 1);
+ extern uint64_t __udivdi3(uint64_t x, uint64_t y);
+ TEST_ASSERT(__udivdi3(15, 2) == 7);
+ extern uint64_t __udivmoddi4(uint64_t x, uint64_t y, uint64_t* z);
+ uint64_t z;
+ TEST_ASSERT(__udivmoddi4(15, 2, &z) == 7);
+ TEST_ASSERT(z == 1);
+ extern unsigned __udivsi3(unsigned x, unsigned y);
+ TEST_ASSERT(__udivsi3(15, 2) == 7);
+ extern uint64_t __umoddi3(uint64_t x, uint64_t y);
+ TEST_ASSERT(__umoddi3(15, 2) == 1);
+ extern unsigned __umodsi3(unsigned x, unsigned y);
+ TEST_ASSERT(__umodsi3(15, 2) == 1);
+ extern uint64_t __umulsidi3(unsigned x, unsigned y);
+ TEST_ASSERT(__umulsidi3(0x10000000, 0x10000000) == 0x100000000000000ULL);
+ extern int __unorddf2(double x, double y);
+ TEST_ASSERT(__unorddf2(1.0, 2.0) == 0);
+ extern int __unordsf2(float x, float y);
+ TEST_ASSERT(__unordsf2(2.0f, 1.0f) == 0);
+
+}
diff --git a/components/esp32/test/test_noinit.c b/components/esp32/test/test_noinit.c
new file mode 100644
index 0000000000..bb1b429392
--- /dev/null
+++ b/components/esp32/test/test_noinit.c
@@ -0,0 +1,123 @@
+#include "unity.h"
+#include "esp_system.h"
+#include "rom/rtc.h"
+#include "esp_log.h"
+
+// This is a test sequence to test behavior of .rtc_noinit and .noinit sections.
+// The values placed into .rtc_noinit section go to RTC SLOW Memory segment and
+// keep their value after reset and deep sleep. Use new added attribute macro
+// RTC_NOINIT_ATTR for this behavior. The second macro - __NOINIT_ATTR places value
+// into .noinit section which goes to SRAM and will not be initialized after reset.
+
+#define RTC_NOINIT_PATTERN 0xAAAAAAAA
+#define _NOINIT_PATTERN 0x55555555
+
+static __NOINIT_ATTR uint32_t noinit_data;
+static RTC_NOINIT_ATTR uint32_t rtc_noinit_data;
+
+extern int _rtc_noinit_start;
+extern int _rtc_noinit_end;
+extern int _noinit_start;
+extern int _noinit_end;
+
+// Pointers to the values
+uint32_t *noinit_val_addr = (uint32_t*)&noinit_data;
+uint32_t *rtc_noinit_val_addr = (uint32_t*)&rtc_noinit_data;
+
+static const char* tag = "noinit_UnitTestMain";
+
+static esp_err_t check_data_seg(uint32_t *value_address, \
+ uint32_t *seg_start, uint32_t *seg_end)
+{
+ esp_err_t result = ESP_FAIL;
+ if (((uint32_t)value_address <= (uint32_t)seg_end) && \
+ ((uint32_t)value_address >= (uint32_t)seg_start)){
+ result = ESP_OK;
+ }
+ return result;
+}
+
+static void setup_attributes(void)
+{
+ rtc_noinit_data = RTC_NOINIT_PATTERN;
+ noinit_data = _NOINIT_PATTERN;
+}
+
+static void init_attributes(void)
+{
+ setup_attributes();
+ printf("noinit_data = 0x%X \n", (uint32_t)*noinit_val_addr);
+ printf("rtc_noinit_data = 0x%X \n", (uint32_t)*rtc_noinit_val_addr);
+ TEST_ASSERT(*noinit_val_addr == noinit_data);
+ TEST_ASSERT(*rtc_noinit_val_addr == rtc_noinit_data);
+}
+
+static void reset_reason_power_on(void)
+{
+ printf("This test case checks behavior of noinit variables POWERON_RESET sequence. \n");
+ RESET_REASON reason = rtc_get_reset_reason(0);
+ ESP_LOGI(tag, "POWERON_RESET reset values = (0x%X), (0x%X), reset reason=(%d)\n", \
+ (uint32_t)*noinit_val_addr, (uint32_t)*rtc_noinit_val_addr, (uint16_t)reason);
+ TEST_ASSERT((reason == POWERON_RESET) || (reason == RTCWDT_RTC_RESET));
+
+ init_attributes();
+ TEST_ASSERT(check_data_seg(noinit_val_addr, \
+ (uint32_t*)&_noinit_start, \
+ (uint32_t*)&_noinit_end) == ESP_OK);
+ TEST_ASSERT(check_data_seg(rtc_noinit_val_addr, \
+ (uint32_t*)&_rtc_noinit_start, \
+ (uint32_t*)&_rtc_noinit_end) == ESP_OK);
+ TEST_ASSERT(_NOINIT_PATTERN == *noinit_val_addr);
+ TEST_ASSERT(RTC_NOINIT_PATTERN == *rtc_noinit_val_addr);
+
+ printf("Next test case will check SOFTWARE_RESET behavior. \n");
+ esp_restart();
+}
+
+static void reset_reason_sw_reset(void)
+{
+ printf("This test case checks behavior of noinit variables after software reset sequence. \n");
+ RESET_REASON reason = rtc_get_reset_reason(0);
+ ESP_LOGI(tag, "SW_CPU_RESET reset values = (0x%X), (0x%X), reset reason=(%d)\n", \
+ (uint32_t)*noinit_val_addr, (uint32_t)*rtc_noinit_val_addr, (uint16_t)reason);
+ TEST_ASSERT(reason == SW_CPU_RESET);
+ TEST_ASSERT(check_data_seg(noinit_val_addr, \
+ (uint32_t*)&_noinit_start, \
+ (uint32_t*)&_noinit_end) == ESP_OK);
+ TEST_ASSERT(check_data_seg(rtc_noinit_val_addr, \
+ (uint32_t*)&_rtc_noinit_start, \
+ (uint32_t*)&_rtc_noinit_end) == ESP_OK);
+ // The ROM bootloader behavior may apply to this assert.
+ // TEST_ASSERT(0x55555555 == *noinit_val_addr);
+ TEST_ASSERT(RTC_NOINIT_PATTERN == *rtc_noinit_val_addr);
+ printf("Go to deep sleep to check DEEP_SLEEP_RESET behavior. \n");
+ esp_sleep_enable_timer_wakeup(2000000);
+ esp_deep_sleep_start();
+}
+
+static void reset_reason_deep_sleep(void)
+{
+ printf("This test case checks behavior of noinit variables after deep sleep reset. \n");
+ RESET_REASON reason = rtc_get_reset_reason(0);
+ ESP_LOGI(tag, "DEEP_SLEEP_RESET reset values = (0x%X), (0x%X), reset reason=(%d)\n", \
+ (uint32_t)*noinit_val_addr, (uint32_t)*rtc_noinit_val_addr, (uint16_t)reason);
+ TEST_ASSERT(reason == DEEPSLEEP_RESET);
+ TEST_ASSERT(check_data_seg(noinit_val_addr, \
+ (uint32_t*)&_noinit_start, \
+ (uint32_t*)&_noinit_end) == ESP_OK);
+ TEST_ASSERT(check_data_seg(rtc_noinit_val_addr, \
+ (uint32_t*)&_rtc_noinit_start, \
+ (uint32_t*)&_rtc_noinit_end) == ESP_OK);
+ TEST_ASSERT(RTC_NOINIT_PATTERN == *rtc_noinit_val_addr);
+ printf("The noinit test cases are done.. \n");
+}
+
+// The lines below are required to suppress GCC warnings about casting of function pointers
+// in unity macro expansion. These warnings may be treated as errors during automated test.
+#pragma GCC diagnostic push // required for GCC
+#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+// The multiple stages test case to check values after certain reset reason
+TEST_CASE_MULTIPLE_STAGES("NOINIT attributes behavior",
+ "[restart][reset=SW_CPU_RESET, DEEPSLEEP_RESET]",
+ reset_reason_power_on, reset_reason_sw_reset, reset_reason_deep_sleep);
+#pragma GCC diagnostic pop // require GCC
diff --git a/components/esp32/test/test_sleep.c b/components/esp32/test/test_sleep.c
index 201c2312e3..abd5a20805 100644
--- a/components/esp32/test/test_sleep.c
+++ b/components/esp32/test/test_sleep.c
@@ -14,6 +14,8 @@
#include "soc/rtc.h" // for wakeup trigger defines
#include "soc/rtc_cntl_reg.h" // for read rtc registers directly (cause)
#include "soc/soc.h" // for direct register read macros
+#include "rom/rtc.h"
+#include "esp_newlib.h"
#define ESP_EXT0_WAKEUP_LEVEL_LOW 0
#define ESP_EXT0_WAKEUP_LEVEL_HIGH 1
@@ -338,3 +340,37 @@ TEST_CASE("disable source trigger behavior", "[deepsleep]")
TEST_ASSERT(err_code == ESP_ERR_INVALID_STATE);
}
+static RTC_DATA_ATTR struct timeval start;
+static void trigger_deepsleep(void)
+{
+ printf("Trigger deep sleep. Waiting for 10 sec ...\n");
+
+ // Simulate the dispersion of the calibration coefficients at start-up.
+ // Corrupt the calibration factor.
+ esp_clk_slowclk_cal_set(esp_clk_slowclk_cal_get() / 2);
+ esp_set_time_from_rtc();
+
+ // Delay for time error accumulation.
+ vTaskDelay(10000/portTICK_RATE_MS);
+
+ // Save start time. Deep sleep.
+ gettimeofday(&start, NULL);
+ esp_sleep_enable_timer_wakeup(1000);
+ // In function esp_deep_sleep_start() uses function esp_sync_counters_rtc_and_frc()
+ // to prevent a negative time after wake up.
+ esp_deep_sleep_start();
+}
+
+static void check_time_deepsleep(void)
+{
+ struct timeval stop;
+ RESET_REASON reason = rtc_get_reset_reason(0);
+ TEST_ASSERT(reason == DEEPSLEEP_RESET);
+ gettimeofday(&stop, NULL);
+ // Time dt_ms must in any case be positive.
+ int dt_ms = (stop.tv_sec - start.tv_sec) * 1000 + (stop.tv_usec - start.tv_usec) / 1000;
+ printf("delta time = %d \n", dt_ms);
+ TEST_ASSERT_MESSAGE(dt_ms > 0, "Time in deep sleep is negative");
+}
+
+TEST_CASE_MULTIPLE_STAGES("check a time after wakeup from deep sleep", "[deepsleep][reset=DEEPSLEEP_RESET]", trigger_deepsleep, check_time_deepsleep);
diff --git a/components/esp32/test/test_wifi_lib_git_commit.c b/components/esp32/test/test_wifi_lib_git_commit.c
new file mode 100644
index 0000000000..8b5633f9b1
--- /dev/null
+++ b/components/esp32/test/test_wifi_lib_git_commit.c
@@ -0,0 +1,14 @@
+/*
+ Tests for the Wi-Fi
+*/
+#include "unity.h"
+#include "esp_log.h"
+#include "esp_wifi_internal.h"
+
+static const char* TAG = "test_wifi_lib_git_commit_id";
+
+TEST_CASE("wifi lib git commit id","[wifi]")
+{
+ TEST_ESP_OK( esp_wifi_internal_git_commit_id_check() );
+}
+
diff --git a/components/esp_http_client/esp_http_client.c b/components/esp_http_client/esp_http_client.c
index 6a6f799e30..e21b93da2f 100644
--- a/components/esp_http_client/esp_http_client.c
+++ b/components/esp_http_client/esp_http_client.c
@@ -33,12 +33,17 @@
static const char *TAG = "HTTP_CLIENT";
+/**
+ * HTTP Buffer
+ */
typedef struct {
- char *data;
- int len;
- char *raw_data;
- int raw_len;
+ char *data; /*!< The HTTP data received from the server */
+ int len; /*!< The HTTP data len received from the server */
+ char *raw_data; /*!< The HTTP data after decoding */
+ int raw_len; /*!< The HTTP data len after decoding */
+ char *output_ptr; /*!< The destination address of the data to be copied to after decoding */
} esp_http_buffer_t;
+
/**
* private HTTP Data structure
*/
@@ -130,7 +135,8 @@ static const char *HTTP_METHOD_MAPPING[] = {
"POST",
"PUT",
"PATCH",
- "DELETE"
+ "DELETE",
+ "HEAD"
};
/**
@@ -232,9 +238,14 @@ static int http_on_body(http_parser *parser, const char *at, size_t length)
{
esp_http_client_t *client = parser->data;
ESP_LOGD(TAG, "http_on_body %d", length);
- client->response->buffer->raw_data = (char*)at;
- client->response->buffer->raw_len = length;
+ client->response->buffer->raw_data = (char *)at;
+ if (client->response->buffer->output_ptr) {
+ memcpy(client->response->buffer->output_ptr, (char *)at, length);
+ client->response->buffer->output_ptr += length;
+ }
+
client->response->data_process += length;
+ client->response->buffer->raw_len += length;
http_dispatch_event(client, HTTP_EVENT_ON_DATA, (void *)at, length);
return 0;
}
@@ -258,12 +269,17 @@ esp_err_t esp_http_client_set_header(esp_http_client_handle_t client, const char
return http_header_set(client->request->headers, key, value);
}
+esp_err_t esp_http_client_get_header(esp_http_client_handle_t client, const char *key, char **value)
+{
+ return http_header_get(client->request->headers, key, value);
+}
+
esp_err_t esp_http_client_delete_header(esp_http_client_handle_t client, const char *key)
{
return http_header_delete(client->request->headers, key);
}
-static esp_err_t _set_config(esp_http_client_handle_t client, esp_http_client_config_t *config)
+static esp_err_t _set_config(esp_http_client_handle_t client, const esp_http_client_config_t *config)
{
client->connection_info.method = config->method;
client->connection_info.port = config->port;
@@ -401,7 +417,7 @@ static esp_err_t esp_http_client_prepare(esp_http_client_handle_t client)
return ESP_OK;
}
-esp_http_client_handle_t esp_http_client_init(esp_http_client_config_t *config)
+esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *config)
{
esp_http_client_handle_t client;
@@ -547,10 +563,10 @@ static esp_err_t esp_http_check_response(esp_http_client_handle_t client)
break;
case HttpStatus_Unauthorized:
auth_header = client->auth_header;
- http_utils_trim_whitespace(&auth_header);
- ESP_LOGI(TAG, "UNAUTHORIZED: %s", auth_header);
- client->redirect_counter ++;
if (auth_header) {
+ http_utils_trim_whitespace(&auth_header);
+ ESP_LOGD(TAG, "UNAUTHORIZED: %s", auth_header);
+ client->redirect_counter ++;
if (http_utils_str_starts_with(auth_header, "Digest") == 0) {
ESP_LOGD(TAG, "type = Digest");
client->connection_info.auth_type = HTTP_AUTH_TYPE_DIGEST;
@@ -559,7 +575,7 @@ static esp_err_t esp_http_check_response(esp_http_client_handle_t client)
client->connection_info.auth_type = HTTP_AUTH_TYPE_BASIC;
} else {
client->connection_info.auth_type = HTTP_AUTH_TYPE_NONE;
- ESP_LOGE(TAG, "Unsupport Auth Type");
+ ESP_LOGE(TAG, "This authentication method is not supported: %s", auth_header);
break;
}
@@ -574,6 +590,9 @@ static esp_err_t esp_http_check_response(esp_http_client_handle_t client)
client->auth_data->nonce = http_utils_get_string_between(auth_header, "nonce=\"", "\"");
client->auth_data->opaque = http_utils_get_string_between(auth_header, "opaque=\"", "\"");
client->process_again = 1;
+ } else {
+ client->connection_info.auth_type = HTTP_AUTH_TYPE_NONE;
+ ESP_LOGW(TAG, "This request requires authentication, but does not provide header information for that");
}
}
return ESP_OK;
@@ -690,6 +709,11 @@ static int esp_http_client_get_data(esp_http_client_handle_t client)
if (client->state < HTTP_STATE_RES_COMPLETE_HEADER) {
return ESP_FAIL;
}
+
+ if (client->connection_info.method == HTTP_METHOD_HEAD) {
+ return 0;
+ }
+
esp_http_buffer_t *res_buffer = client->response->buffer;
ESP_LOGD(TAG, "data_process=%d, content_length=%d", client->response->data_process, client->response->content_length);
@@ -738,14 +762,13 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)
if (rlen <= 0) {
return ridx;
}
+ res_buffer->output_ptr = buffer + ridx;
http_parser_execute(client->parser, client->parser_settings, res_buffer->data, rlen);
+ ridx += res_buffer->raw_len;
+ need_read -= res_buffer->raw_len;
- if (res_buffer->raw_len) {
- memcpy(buffer + ridx, res_buffer->raw_data, res_buffer->raw_len);
- ridx += res_buffer->raw_len;
- need_read -= res_buffer->raw_len;
- }
res_buffer->raw_len = 0; //clear
+ res_buffer->output_ptr = NULL;
}
return ridx;
@@ -754,6 +777,9 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)
esp_err_t esp_http_client_perform(esp_http_client_handle_t client)
{
esp_err_t err;
+ if (client == NULL) {
+ return ESP_ERR_INVALID_ARG;
+ }
do {
if ((err = esp_http_client_open(client, client->post_len)) != ESP_OK) {
return err;
@@ -844,6 +870,11 @@ esp_err_t esp_http_client_open(esp_http_client_handle_t client, int write_len)
client->transport = transport_list_get_transport(client->transport_list, client->connection_info.scheme);
if (client->transport == NULL) {
ESP_LOGE(TAG, "No transport found");
+#ifndef CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS
+ if (strcasecmp(client->connection_info.scheme, "https") == 0) {
+ ESP_LOGE(TAG, "Please enable HTTPS at menuconfig to allow requesting via https");
+ }
+#endif
return ESP_ERR_HTTP_INVALID_TRANSPORT;
}
if (transport_connect(client->transport, client->connection_info.host, client->connection_info.port, client->timeout_ms) < 0) {
@@ -952,7 +983,13 @@ esp_err_t esp_http_client_set_post_field(esp_http_client_handle_t client, const
client->post_len = len;
ESP_LOGD(TAG, "set post file length = %d", len);
if (client->post_data) {
- err = esp_http_client_set_header(client, "Content-Type", "application/x-www-form-urlencoded");
+ char *value = NULL;
+ if ((err = esp_http_client_get_header(client, "Content-Type", &value)) != ESP_OK) {
+ return err;
+ }
+ if (value == NULL) {
+ err = esp_http_client_set_header(client, "Content-Type", "application/x-www-form-urlencoded");
+ }
} else {
client->post_len = 0;
err = esp_http_client_set_header(client, "Content-Type", NULL);
@@ -983,3 +1020,14 @@ bool esp_http_client_is_chunked_response(esp_http_client_handle_t client)
{
return client->response->is_chunked;
}
+
+esp_http_client_transport_t esp_http_client_get_transport_type(esp_http_client_handle_t client)
+{
+ if (!strcmp(client->connection_info.scheme, "https") ) {
+ return HTTP_TRANSPORT_OVER_SSL;
+ } else if (!strcmp(client->connection_info.scheme, "http")) {
+ return HTTP_TRANSPORT_OVER_TCP;
+ } else {
+ return HTTP_TRANSPORT_UNKNOWN;
+ }
+}
diff --git a/components/esp_http_client/include/esp_http_client.h b/components/esp_http_client/include/esp_http_client.h
index 687cf8d3b5..159931c2c8 100644
--- a/components/esp_http_client/include/esp_http_client.h
+++ b/components/esp_http_client/include/esp_http_client.h
@@ -76,6 +76,7 @@ typedef enum {
HTTP_METHOD_PUT, /*!< HTTP PUT Method */
HTTP_METHOD_PATCH, /*!< HTTP PATCH Method */
HTTP_METHOD_DELETE, /*!< HTTP DELETE Method */
+ HTTP_METHOD_HEAD, /*!< HTTP HEAD Method */
HTTP_METHOD_MAX,
} esp_http_client_method_t;
@@ -131,7 +132,7 @@ typedef struct {
* - `esp_http_client_handle_t`
* - NULL if any errors
*/
-esp_http_client_handle_t esp_http_client_init(esp_http_client_config_t *config);
+esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *config);
/**
* @brief Invoke this function after `esp_http_client_init` and all the options calls are made, and will perform the
@@ -168,7 +169,7 @@ esp_err_t esp_http_client_perform(esp_http_client_handle_t client);
esp_err_t esp_http_client_set_url(esp_http_client_handle_t client, const char *url);
/**
- * @brief Set post data, this function must be called before `esp_http_client_finalize_open` or perform
+ * @brief Set post data, this function must be called before `esp_http_client_perform`.
* Note: The data parameter passed to this function is a pointer and this function will not copy the data
*
* @param[in] client The esp_http_client handle
@@ -205,6 +206,22 @@ int esp_http_client_get_post_field(esp_http_client_handle_t client, char **data)
*/
esp_err_t esp_http_client_set_header(esp_http_client_handle_t client, const char *key, const char *value);
+/**
+ * @brief Get http request header.
+ * The value parameter will be set to NULL if there is no header which is same as
+ * the key specified, otherwise the address of header value will be assigned to value parameter.
+ * This function must be called after `esp_http_client_init`.
+ *
+ * @param[in] client The esp_http_client handle
+ * @param[in] key The header key
+ * @param[out] value The header value
+ *
+ * @return
+ * - ESP_OK
+ * - ESP_FAIL
+ */
+esp_err_t esp_http_client_get_header(esp_http_client_handle_t client, const char *key, char **value);
+
/**
* @brief Set http request method
*
@@ -266,7 +283,7 @@ int esp_http_client_fetch_headers(esp_http_client_handle_t client);
/**
- * @brief Check response data is chunked, must call after `esp_http_client_finalize_open`
+ * @brief Check response data is chunked
*
* @param[in] client The esp_http_client handle
*
@@ -289,7 +306,7 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)
/**
- * @brief Get http response status code, the valid value if this function invoke after `esp_http_client_perform` or `esp_http_client_finalize_open`
+ * @brief Get http response status code, the valid value if this function invoke after `esp_http_client_perform`
*
* @param[in] client The esp_http_client handle
*
@@ -299,7 +316,7 @@ int esp_http_client_get_status_code(esp_http_client_handle_t client);
/**
* @brief Get http response content length (from header Content-Length)
- * the valid value if this function invoke after `esp_http_client_perform` or `esp_http_client_finalize_open`
+ * the valid value if this function invoke after `esp_http_client_perform`
*
* @param[in] client The esp_http_client handle
*
@@ -334,6 +351,17 @@ esp_err_t esp_http_client_close(esp_http_client_handle_t client);
*/
esp_err_t esp_http_client_cleanup(esp_http_client_handle_t client);
+/**
+ * @brief Get transport type
+ *
+ * @param[in] client The esp_http_client handle
+ *
+ * @return
+ * - HTTP_TRANSPORT_UNKNOWN
+ * - HTTP_TRANSPORT_OVER_TCP
+ * - HTTP_TRANSPORT_OVER_SSL
+ */
+esp_http_client_transport_t esp_http_client_get_transport_type(esp_http_client_handle_t client);
#ifdef __cplusplus
@@ -341,4 +369,4 @@ esp_err_t esp_http_client_cleanup(esp_http_client_handle_t client);
#endif
-#endif
+#endif
\ No newline at end of file
diff --git a/components/esp_http_client/lib/http_auth.c b/components/esp_http_client/lib/http_auth.c
index cd1d4ef721..c406937c96 100644
--- a/components/esp_http_client/lib/http_auth.c
+++ b/components/esp_http_client/lib/http_auth.c
@@ -136,15 +136,15 @@ char *http_auth_basic(const char *username, const char *password)
{
int out;
char *user_info = NULL;
- char *digest = calloc(1, MD5_MAX_LEN + 7);
- HTTP_MEM_CHECK(TAG, digest, goto _basic_exit);
+ char *digest = NULL;
+ size_t n = 0;
asprintf(&user_info, "%s:%s", username, password);
- HTTP_MEM_CHECK(TAG, user_info, goto _basic_exit);
- if (user_info == NULL) {
- goto _basic_exit;
- }
+ HTTP_MEM_CHECK(TAG, user_info, return NULL);
+ mbedtls_base64_encode(NULL, 0, &n, (const unsigned char *)user_info, strlen(user_info));
+ digest = calloc(1, 6 + n + 1);
+ HTTP_MEM_CHECK(TAG, digest, goto _basic_exit);
strcpy(digest, "Basic ");
- mbedtls_base64_encode((unsigned char *)digest + 6, MD5_MAX_LEN, (size_t *)&out, (const unsigned char *)user_info, strlen(user_info));
+ mbedtls_base64_encode((unsigned char *)digest + 6, n, (size_t *)&out, (const unsigned char *)user_info, strlen(user_info));
_basic_exit:
free(user_info);
return digest;
diff --git a/components/esp_http_client/lib/http_utils.c b/components/esp_http_client/lib/http_utils.c
index 2ccc501313..2e65888abc 100644
--- a/components/esp_http_client/lib/http_utils.c
+++ b/components/esp_http_client/lib/http_utils.c
@@ -63,8 +63,14 @@ char *http_utils_assign_string(char **str, const char *new_str, int len)
void http_utils_trim_whitespace(char **str)
{
- char *end;
- char *start = *str;
+ char *end, *start;
+ if (str == NULL) {
+ return;
+ }
+ start = *str;
+ if (start == NULL) {
+ return;
+ }
// Trim leading space
while (isspace((unsigned char)*start)) start ++;
diff --git a/components/esp_http_client/lib/transport_ssl.c b/components/esp_http_client/lib/transport_ssl.c
index 8a3c49c0ff..bb07c92455 100644
--- a/components/esp_http_client/lib/transport_ssl.c
+++ b/components/esp_http_client/lib/transport_ssl.c
@@ -206,12 +206,14 @@ static int ssl_write(transport_handle_t t, const char *buffer, int len, int time
static int ssl_read(transport_handle_t t, char *buffer, int len, int timeout_ms)
{
- int ret;
+ int poll = -1, ret;
transport_ssl_t *ssl = transport_get_context_data(t);
- ret = mbedtls_ssl_read(&ssl->ctx, (unsigned char *)buffer, len);
- if (ret == 0) {
- return -1;
+ if (mbedtls_ssl_get_bytes_avail(&ssl->ctx) <= 0) {
+ if ((poll = transport_poll_read(t, timeout_ms)) <= 0) {
+ return poll;
+ }
}
+ ret = mbedtls_ssl_read(&ssl->ctx, (unsigned char *)buffer, len);
return ret;
}
diff --git a/components/esp_https_ota/CMakeLists.txt b/components/esp_https_ota/CMakeLists.txt
new file mode 100644
index 0000000000..bfc6c12054
--- /dev/null
+++ b/components/esp_https_ota/CMakeLists.txt
@@ -0,0 +1,7 @@
+set(COMPONENT_ADD_INCLUDEDIRS include)
+set(COMPONENT_SRCDIRS "src")
+
+set(COMPONENT_REQUIRES esp_http_client)
+set(COMPONENT_PRIV_REQUIRES log app_update)
+
+register_component()
diff --git a/components/esp_https_ota/component.mk b/components/esp_https_ota/component.mk
new file mode 100644
index 0000000000..ebe80ffbe6
--- /dev/null
+++ b/components/esp_https_ota/component.mk
@@ -0,0 +1,3 @@
+COMPONENT_SRCDIRS := src
+
+COMPONENT_ADD_INCLUDEDIRS := include
diff --git a/components/esp_https_ota/include/esp_https_ota.h b/components/esp_https_ota/include/esp_https_ota.h
new file mode 100644
index 0000000000..157195601c
--- /dev/null
+++ b/components/esp_https_ota/include/esp_https_ota.h
@@ -0,0 +1,45 @@
+// Copyright 2017-2018 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.
+
+#pragma once
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief HTTPS OTA Firmware upgrade.
+ *
+ * This function performs HTTPS OTA Firmware upgrade
+ *
+ * @param[in] config pointer to esp_http_client_config_t structure.
+ *
+ * @note For secure HTTPS updates, the `cert_pem` member of `config`
+ * structure must be set to the server certificate.
+ *
+ * @return
+ * - ESP_OK: OTA data updated, next reboot will use specified partition.
+ * - ESP_FAIL: For generic failure.
+ * - ESP_ERR_OTA_VALIDATE_FAILED: Invalid app image
+ * - ESP_ERR_NO_MEM: Cannot allocate memory for OTA operation.
+ * - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
+ * - For other return codes, refer OTA documentation in esp-idf's app_update component.
+ */
+esp_err_t esp_https_ota(const esp_http_client_config_t *config);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/components/esp_https_ota/src/esp_https_ota.c b/components/esp_https_ota/src/esp_https_ota.c
new file mode 100644
index 0000000000..9929a18560
--- /dev/null
+++ b/components/esp_https_ota/src/esp_https_ota.c
@@ -0,0 +1,130 @@
+// Copyright 2017-2018 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.
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define OTA_BUF_SIZE 256
+static const char *TAG = "esp_https_ota";
+
+static void http_cleanup(esp_http_client_handle_t client)
+{
+ esp_http_client_close(client);
+ esp_http_client_cleanup(client);
+}
+
+esp_err_t esp_https_ota(const esp_http_client_config_t *config)
+{
+ if (!config) {
+ ESP_LOGE(TAG, "esp_http_client config not found");
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ if (!config->cert_pem) {
+ ESP_LOGE(TAG, "Server certificate not found in esp_http_client config");
+ return ESP_FAIL;
+ }
+
+ esp_http_client_handle_t client = esp_http_client_init(config);
+ if (client == NULL) {
+ ESP_LOGE(TAG, "Failed to initialise HTTP connection");
+ return ESP_FAIL;
+ }
+
+ if (esp_http_client_get_transport_type(client) != HTTP_TRANSPORT_OVER_SSL) {
+ ESP_LOGE(TAG, "Transport is not over HTTPS");
+ return ESP_FAIL;
+ }
+
+ esp_err_t err = esp_http_client_open(client, 0);
+ if (err != ESP_OK) {
+ esp_http_client_cleanup(client);
+ ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
+ return err;
+ }
+ esp_http_client_fetch_headers(client);
+
+ esp_ota_handle_t update_handle = 0;
+ const esp_partition_t *update_partition = NULL;
+ ESP_LOGI(TAG, "Starting OTA...");
+ update_partition = esp_ota_get_next_update_partition(NULL);
+ if (update_partition == NULL) {
+ ESP_LOGE(TAG, "Passive OTA partition not found");
+ http_cleanup(client);
+ return ESP_FAIL;
+ }
+ ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x",
+ update_partition->subtype, update_partition->address);
+
+ err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
+ if (err != ESP_OK) {
+ ESP_LOGE(TAG, "esp_ota_begin failed, error=%d", err);
+ http_cleanup(client);
+ return err;
+ }
+ ESP_LOGI(TAG, "esp_ota_begin succeeded");
+ ESP_LOGI(TAG, "Please Wait. This may take time");
+
+ esp_err_t ota_write_err = ESP_OK;
+ char *upgrade_data_buf = (char *)malloc(OTA_BUF_SIZE);
+ if (!upgrade_data_buf) {
+ ESP_LOGE(TAG, "Couldn't allocate memory to upgrade data buffer");
+ return ESP_ERR_NO_MEM;
+ }
+ int binary_file_len = 0;
+ while (1) {
+ int data_read = esp_http_client_read(client, upgrade_data_buf, OTA_BUF_SIZE);
+ if (data_read == 0) {
+ ESP_LOGI(TAG, "Connection closed,all data received");
+ break;
+ }
+ if (data_read < 0) {
+ ESP_LOGE(TAG, "Error: SSL data read error");
+ break;
+ }
+ if (data_read > 0) {
+ ota_write_err = esp_ota_write( update_handle, (const void *)upgrade_data_buf, data_read);
+ if (ota_write_err != ESP_OK) {
+ break;
+ }
+ binary_file_len += data_read;
+ ESP_LOGD(TAG, "Written image length %d", binary_file_len);
+ }
+ }
+ free(upgrade_data_buf);
+ http_cleanup(client);
+ ESP_LOGD(TAG, "Total binary data length writen: %d", binary_file_len);
+
+ esp_err_t ota_end_err = esp_ota_end(update_handle);
+ if (ota_write_err != ESP_OK) {
+ ESP_LOGE(TAG, "Error: esp_ota_write failed! err=0x%d", err);
+ return ota_write_err;
+ } else if (ota_end_err != ESP_OK) {
+ ESP_LOGE(TAG, "Error: esp_ota_end failed! err=0x%d. Image is invalid", ota_end_err);
+ return ota_end_err;
+ }
+
+ err = esp_ota_set_boot_partition(update_partition);
+ if (err != ESP_OK) {
+ ESP_LOGE(TAG, "esp_ota_set_boot_partition failed! err=0x%d", err);
+ return err;
+ }
+ ESP_LOGI(TAG, "esp_ota_set_boot_partition succeeded");
+
+ return ESP_OK;
+}
diff --git a/components/espcoredump/espcoredump.py b/components/espcoredump/espcoredump.py
index a1091a006a..321941fd1c 100755
--- a/components/espcoredump/espcoredump.py
+++ b/components/espcoredump/espcoredump.py
@@ -22,7 +22,7 @@ except ImportError:
print "Esptool is not found! Set proper $IDF_PATH in environment."
sys.exit(2)
-__version__ = "0.1-dev"
+__version__ = "0.2-dev"
if os.name == 'nt':
CLOSE_FDS = False
@@ -77,12 +77,6 @@ class BinStruct(object):
keys = self.__class__.fields
return struct.pack(self.__class__.format, *(self.__dict__[k] for k in keys))
-# def __str__(self):
-# keys = self.__class__.fields
-# return (self.__class__.__name__ + "({" +
-# ", ".join("%s:%r" % (k, self.__dict__[k]) for k in keys) +
-# "})")
-
class Elf32FileHeader(BinStruct):
"""ELF32 file header
@@ -304,14 +298,12 @@ class ESPCoreDumpElfFile(esptool.ELFFile):
raise ESPCoreDumpError("%s does not appear to be an Xtensa ELF file. e_machine=%04x" % (self.name, machine))
self.e_type = type
self.e_machine = machine
+ self.sections = []
+ self.program_segments = []
if shnum > 0:
self._read_sections(f, shoff, shstrndx)
- else:
- self.sections = []
- if phnum > 0:
- self._read_program_segments(f, phoff, phentsize, phnum)
- else:
- self.program_segments = []
+ if phnum > 0:
+ self._read_program_segments(f, phoff, phentsize, phnum)
def _read_sections(self, f, section_header_offs, shstrndx):
"""Reads core dump sections from ELF file
@@ -373,17 +365,15 @@ class ESPCoreDumpElfFile(esptool.ELFFile):
def read_program_header(offs):
type,offset,vaddr,_paddr,filesz,_memsz,flags,_align = struct.unpack_from("flow_ctrl_enable;
#else
if(config->flow_ctrl_enable == true) {
- ESP_LOGE(TAG, "eth flow ctrl init err!!! Please run idf.py menuconfig and make sure DMA_RX_BUF_NUM > 9 .");
+ ESP_LOGE(TAG, "eth flow ctrl init err!!! Please run menuconfig and make sure DMA_RX_BUF_NUM > 9 .");
}
emac_config.emac_flow_ctrl_enable = false;
#endif
diff --git a/components/expat/CMakeLists.txt b/components/expat/CMakeLists.txt
index 5791a26599..e94f775124 100644
--- a/components/expat/CMakeLists.txt
+++ b/components/expat/CMakeLists.txt
@@ -1,15 +1,12 @@
-set(COMPONENT_ADD_INCLUDEDIRS port/include include/expat)
-set(COMPONENT_SRCDIRS library port)
+set(COMPONENT_ADD_INCLUDEDIRS expat/expat/lib port/include)
+set(COMPONENT_SRCDIRS expat/expat/lib)
set(COMPONENT_REQUIRES)
register_component()
component_compile_definitions(HAVE_EXPAT_CONFIG_H)
+component_compile_definitions(HAVE_GETRANDOM)
-# patch around warnings in third-party files
-set_source_files_properties(
- library/xmlparse.c
- PROPERTIES COMPILE_FLAGS
- -Wno-unused-function
- )
+# Temporary suppress "fallthrough" warnings until they are fixed in expat repo
+component_compile_options(-Wno-implicit-fallthrough)
diff --git a/components/expat/COPYING b/components/expat/COPYING
deleted file mode 100644
index 092c83baee..0000000000
--- a/components/expat/COPYING
+++ /dev/null
@@ -1,21 +0,0 @@
-Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper
-Copyright (c) 2001-2016 Expat maintainers
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/components/expat/README b/components/expat/README
deleted file mode 100644
index a7d28450d5..0000000000
--- a/components/expat/README
+++ /dev/null
@@ -1,139 +0,0 @@
-
- Expat, Release 2.2.0
-
-This is Expat, a C library for parsing XML, written by James Clark.
-Expat is a stream-oriented XML parser. This means that you register
-handlers with the parser before starting the parse. These handlers
-are called when the parser discovers the associated structures in the
-document being parsed. A start tag is an example of the kind of
-structures for which you may register handlers.
-
-Windows users should use the expat_win32bin package, which includes
-both precompiled libraries and executables, and source code for
-developers.
-
-Expat is free software. You may copy, distribute, and modify it under
-the terms of the License contained in the file COPYING distributed
-with this package. This license is the same as the MIT/X Consortium
-license.
-
-Versions of Expat that have an odd minor version (the middle number in
-the release above), are development releases and should be considered
-as beta software. Releases with even minor version numbers are
-intended to be production grade software.
-
-If you are building Expat from a check-out from the CVS repository,
-you need to run a script that generates the configure script using the
-GNU autoconf and libtool tools. To do this, you need to have
-autoconf 2.58 or newer. Run the script like this:
-
- ./buildconf.sh
-
-Once this has been done, follow the same instructions as for building
-from a source distribution.
-
-To build Expat from a source distribution, you first run the
-configuration shell script in the top level distribution directory:
-
- ./configure
-
-There are many options which you may provide to configure (which you
-can discover by running configure with the --help option). But the
-one of most interest is the one that sets the installation directory.
-By default, the configure script will set things up to install
-libexpat into /usr/local/lib, expat.h into /usr/local/include, and
-xmlwf into /usr/local/bin. If, for example, you'd prefer to install
-into /home/me/mystuff/lib, /home/me/mystuff/include, and
-/home/me/mystuff/bin, you can tell configure about that with:
-
- ./configure --prefix=/home/me/mystuff
-
-Another interesting option is to enable 64-bit integer support for
-line and column numbers and the over-all byte index:
-
- ./configure CPPFLAGS=-DXML_LARGE_SIZE
-
-However, such a modification would be a breaking change to the ABI
-and is therefore not recommended for general use - e.g. as part of
-a Linux distribution - but rather for builds with special requirements.
-
-After running the configure script, the "make" command will build
-things and "make install" will install things into their proper
-location. Have a look at the "Makefile" to learn about additional
-"make" options. Note that you need to have write permission into
-the directories into which things will be installed.
-
-If you are interested in building Expat to provide document
-information in UTF-16 encoding rather than the default UTF-8, follow
-these instructions (after having run "make distclean"):
-
- 1. For UTF-16 output as unsigned short (and version/error
- strings as char), run:
-
- ./configure CPPFLAGS=-DXML_UNICODE
-
- For UTF-16 output as wchar_t (incl. version/error strings),
- run:
-
- ./configure CFLAGS="-g -O2 -fshort-wchar" \
- CPPFLAGS=-DXML_UNICODE_WCHAR_T
-
- 2. Edit the MakeFile, changing:
-
- LIBRARY = libexpat.la
-
- to:
-
- LIBRARY = libexpatw.la
-
- (Note the additional "w" in the library name.)
-
- 3. Run "make buildlib" (which builds the library only).
- Or, to save step 2, run "make buildlib LIBRARY=libexpatw.la".
-
- 4. Run "make installlib" (which installs the library only).
- Or, if step 2 was omitted, run "make installlib LIBRARY=libexpatw.la".
-
-Using DESTDIR or INSTALL_ROOT is enabled, with INSTALL_ROOT being the default
-value for DESTDIR, and the rest of the make file using only DESTDIR.
-It works as follows:
- $ make install DESTDIR=/path/to/image
-overrides the in-makefile set DESTDIR, while both
- $ INSTALL_ROOT=/path/to/image make install
- $ make install INSTALL_ROOT=/path/to/image
-use DESTDIR=$(INSTALL_ROOT), even if DESTDIR eventually is defined in the
-environment, because variable-setting priority is
-1) commandline
-2) in-makefile
-3) environment
-
-Note: This only applies to the Expat library itself, building UTF-16 versions
-of xmlwf and the tests is currently not supported.
-
-Note for Solaris users: The "ar" command is usually located in
-"/usr/ccs/bin", which is not in the default PATH. You will need to
-add this to your path for the "make" command, and probably also switch
-to GNU make (the "make" found in /usr/ccs/bin does not seem to work
-properly -- apparently it does not understand .PHONY directives). If
-you're using ksh or bash, use this command to build:
-
- PATH=/usr/ccs/bin:$PATH make
-
-When using Expat with a project using autoconf for configuration, you
-can use the probing macro in conftools/expat.m4 to determine how to
-include Expat. See the comments at the top of that file for more
-information.
-
-A reference manual is available in the file doc/reference.html in this
-distribution.
-
-The homepage for this project is http://www.libexpat.org/. There
-are links there to connect you to the bug reports page. If you need
-to report a bug when you don't have access to a browser, you may also
-send a bug report by email to expat-bugs@mail.libexpat.org.
-
-Discussion related to the direction of future expat development takes
-place on expat-discuss@mail.libexpat.org. Archives of this list and
-other Expat-related lists may be found at:
-
- http://mail.libexpat.org/mailman/listinfo/
diff --git a/components/expat/component.mk b/components/expat/component.mk
index 0ee1199d1b..851f6a8c38 100644
--- a/components/expat/component.mk
+++ b/components/expat/component.mk
@@ -1,9 +1,12 @@
#
# Component Makefile
#
-COMPONENT_ADD_INCLUDEDIRS := port/include include/expat
+COMPONENT_ADD_INCLUDEDIRS := expat/expat/lib port/include
-COMPONENT_SRCDIRS := library port
+COMPONENT_SRCDIRS := expat/expat/lib port
-CFLAGS += -Wno-unused-function -DHAVE_EXPAT_CONFIG_H
+CFLAGS += -DHAVE_EXPAT_CONFIG_H -DHAVE_GETRANDOM
+# Temporary suppress "fallthrough" warnings until they are fixed in expat repo
+CFLAGS += -Wno-implicit-fallthrough
+COMPONENT_SUBMODULES += expat
diff --git a/components/expat/expat b/components/expat/expat
new file mode 160000
index 0000000000..968b8cc46d
--- /dev/null
+++ b/components/expat/expat
@@ -0,0 +1 @@
+Subproject commit 968b8cc46dbee47b83318d5f31a8e7907199614b
diff --git a/components/expat/include/expat/ascii.h b/components/expat/include/expat/ascii.h
deleted file mode 100644
index d10530b09b..0000000000
--- a/components/expat/include/expat/ascii.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#define ASCII_A 0x41
-#define ASCII_B 0x42
-#define ASCII_C 0x43
-#define ASCII_D 0x44
-#define ASCII_E 0x45
-#define ASCII_F 0x46
-#define ASCII_G 0x47
-#define ASCII_H 0x48
-#define ASCII_I 0x49
-#define ASCII_J 0x4A
-#define ASCII_K 0x4B
-#define ASCII_L 0x4C
-#define ASCII_M 0x4D
-#define ASCII_N 0x4E
-#define ASCII_O 0x4F
-#define ASCII_P 0x50
-#define ASCII_Q 0x51
-#define ASCII_R 0x52
-#define ASCII_S 0x53
-#define ASCII_T 0x54
-#define ASCII_U 0x55
-#define ASCII_V 0x56
-#define ASCII_W 0x57
-#define ASCII_X 0x58
-#define ASCII_Y 0x59
-#define ASCII_Z 0x5A
-
-#define ASCII_a 0x61
-#define ASCII_b 0x62
-#define ASCII_c 0x63
-#define ASCII_d 0x64
-#define ASCII_e 0x65
-#define ASCII_f 0x66
-#define ASCII_g 0x67
-#define ASCII_h 0x68
-#define ASCII_i 0x69
-#define ASCII_j 0x6A
-#define ASCII_k 0x6B
-#define ASCII_l 0x6C
-#define ASCII_m 0x6D
-#define ASCII_n 0x6E
-#define ASCII_o 0x6F
-#define ASCII_p 0x70
-#define ASCII_q 0x71
-#define ASCII_r 0x72
-#define ASCII_s 0x73
-#define ASCII_t 0x74
-#define ASCII_u 0x75
-#define ASCII_v 0x76
-#define ASCII_w 0x77
-#define ASCII_x 0x78
-#define ASCII_y 0x79
-#define ASCII_z 0x7A
-
-#define ASCII_0 0x30
-#define ASCII_1 0x31
-#define ASCII_2 0x32
-#define ASCII_3 0x33
-#define ASCII_4 0x34
-#define ASCII_5 0x35
-#define ASCII_6 0x36
-#define ASCII_7 0x37
-#define ASCII_8 0x38
-#define ASCII_9 0x39
-
-#define ASCII_TAB 0x09
-#define ASCII_SPACE 0x20
-#define ASCII_EXCL 0x21
-#define ASCII_QUOT 0x22
-#define ASCII_AMP 0x26
-#define ASCII_APOS 0x27
-#define ASCII_MINUS 0x2D
-#define ASCII_PERIOD 0x2E
-#define ASCII_COLON 0x3A
-#define ASCII_SEMI 0x3B
-#define ASCII_LT 0x3C
-#define ASCII_EQUALS 0x3D
-#define ASCII_GT 0x3E
-#define ASCII_LSQB 0x5B
-#define ASCII_RSQB 0x5D
-#define ASCII_UNDERSCORE 0x5F
-#define ASCII_LPAREN 0x28
-#define ASCII_RPAREN 0x29
-#define ASCII_FF 0x0C
-#define ASCII_SLASH 0x2F
-#define ASCII_HASH 0x23
-#define ASCII_PIPE 0x7C
-#define ASCII_COMMA 0x2C
diff --git a/components/expat/include/expat/asciitab.h b/components/expat/include/expat/asciitab.h
deleted file mode 100644
index 79a15c28ca..0000000000
--- a/components/expat/include/expat/asciitab.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
-/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
-/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
-/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
-/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
-/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
-/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
-/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
-/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
-/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
-/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/components/expat/include/expat/expat.h b/components/expat/include/expat/expat.h
deleted file mode 100644
index 086e24b39c..0000000000
--- a/components/expat/include/expat/expat.h
+++ /dev/null
@@ -1,1048 +0,0 @@
-/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#ifndef Expat_INCLUDED
-#define Expat_INCLUDED 1
-
-#ifdef __VMS
-/* 0 1 2 3 0 1 2 3
- 1234567890123456789012345678901 1234567890123456789012345678901 */
-#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler
-#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler
-#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler
-#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg
-#endif
-
-#include
-#include "expat_external.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct XML_ParserStruct;
-typedef struct XML_ParserStruct *XML_Parser;
-
-/* Should this be defined using stdbool.h when C99 is available? */
-typedef unsigned char XML_Bool;
-#define XML_TRUE ((XML_Bool) 1)
-#define XML_FALSE ((XML_Bool) 0)
-
-/* The XML_Status enum gives the possible return values for several
- API functions. The preprocessor #defines are included so this
- stanza can be added to code that still needs to support older
- versions of Expat 1.95.x:
-
- #ifndef XML_STATUS_OK
- #define XML_STATUS_OK 1
- #define XML_STATUS_ERROR 0
- #endif
-
- Otherwise, the #define hackery is quite ugly and would have been
- dropped.
-*/
-enum XML_Status {
- XML_STATUS_ERROR = 0,
-#define XML_STATUS_ERROR XML_STATUS_ERROR
- XML_STATUS_OK = 1,
-#define XML_STATUS_OK XML_STATUS_OK
- XML_STATUS_SUSPENDED = 2
-#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED
-};
-
-enum XML_Error {
- XML_ERROR_NONE,
- XML_ERROR_NO_MEMORY,
- XML_ERROR_SYNTAX,
- XML_ERROR_NO_ELEMENTS,
- XML_ERROR_INVALID_TOKEN,
- XML_ERROR_UNCLOSED_TOKEN,
- XML_ERROR_PARTIAL_CHAR,
- XML_ERROR_TAG_MISMATCH,
- XML_ERROR_DUPLICATE_ATTRIBUTE,
- XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
- XML_ERROR_PARAM_ENTITY_REF,
- XML_ERROR_UNDEFINED_ENTITY,
- XML_ERROR_RECURSIVE_ENTITY_REF,
- XML_ERROR_ASYNC_ENTITY,
- XML_ERROR_BAD_CHAR_REF,
- XML_ERROR_BINARY_ENTITY_REF,
- XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
- XML_ERROR_MISPLACED_XML_PI,
- XML_ERROR_UNKNOWN_ENCODING,
- XML_ERROR_INCORRECT_ENCODING,
- XML_ERROR_UNCLOSED_CDATA_SECTION,
- XML_ERROR_EXTERNAL_ENTITY_HANDLING,
- XML_ERROR_NOT_STANDALONE,
- XML_ERROR_UNEXPECTED_STATE,
- XML_ERROR_ENTITY_DECLARED_IN_PE,
- XML_ERROR_FEATURE_REQUIRES_XML_DTD,
- XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING,
- /* Added in 1.95.7. */
- XML_ERROR_UNBOUND_PREFIX,
- /* Added in 1.95.8. */
- XML_ERROR_UNDECLARING_PREFIX,
- XML_ERROR_INCOMPLETE_PE,
- XML_ERROR_XML_DECL,
- XML_ERROR_TEXT_DECL,
- XML_ERROR_PUBLICID,
- XML_ERROR_SUSPENDED,
- XML_ERROR_NOT_SUSPENDED,
- XML_ERROR_ABORTED,
- XML_ERROR_FINISHED,
- XML_ERROR_SUSPEND_PE,
- /* Added in 2.0. */
- XML_ERROR_RESERVED_PREFIX_XML,
- XML_ERROR_RESERVED_PREFIX_XMLNS,
- XML_ERROR_RESERVED_NAMESPACE_URI
-};
-
-enum XML_Content_Type {
- XML_CTYPE_EMPTY = 1,
- XML_CTYPE_ANY,
- XML_CTYPE_MIXED,
- XML_CTYPE_NAME,
- XML_CTYPE_CHOICE,
- XML_CTYPE_SEQ
-};
-
-enum XML_Content_Quant {
- XML_CQUANT_NONE,
- XML_CQUANT_OPT,
- XML_CQUANT_REP,
- XML_CQUANT_PLUS
-};
-
-/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
- XML_CQUANT_NONE, and the other fields will be zero or NULL.
- If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
- numchildren will contain number of elements that may be mixed in
- and children point to an array of XML_Content cells that will be
- all of XML_CTYPE_NAME type with no quantification.
-
- If type == XML_CTYPE_NAME, then the name points to the name, and
- the numchildren field will be zero and children will be NULL. The
- quant fields indicates any quantifiers placed on the name.
-
- CHOICE and SEQ will have name NULL, the number of children in
- numchildren and children will point, recursively, to an array
- of XML_Content cells.
-
- The EMPTY, ANY, and MIXED types will only occur at top level.
-*/
-
-typedef struct XML_cp XML_Content;
-
-struct XML_cp {
- enum XML_Content_Type type;
- enum XML_Content_Quant quant;
- XML_Char * name;
- unsigned int numchildren;
- XML_Content * children;
-};
-
-
-/* This is called for an element declaration. See above for
- description of the model argument. It's the caller's responsibility
- to free model when finished with it.
-*/
-typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,
- const XML_Char *name,
- XML_Content *model);
-
-XMLPARSEAPI(void)
-XML_SetElementDeclHandler(XML_Parser parser,
- XML_ElementDeclHandler eldecl);
-
-/* The Attlist declaration handler is called for *each* attribute. So
- a single Attlist declaration with multiple attributes declared will
- generate multiple calls to this handler. The "default" parameter
- may be NULL in the case of the "#IMPLIED" or "#REQUIRED"
- keyword. The "isrequired" parameter will be true and the default
- value will be NULL in the case of "#REQUIRED". If "isrequired" is
- true and default is non-NULL, then this is a "#FIXED" default.
-*/
-typedef void (XMLCALL *XML_AttlistDeclHandler) (
- void *userData,
- const XML_Char *elname,
- const XML_Char *attname,
- const XML_Char *att_type,
- const XML_Char *dflt,
- int isrequired);
-
-XMLPARSEAPI(void)
-XML_SetAttlistDeclHandler(XML_Parser parser,
- XML_AttlistDeclHandler attdecl);
-
-/* The XML declaration handler is called for *both* XML declarations
- and text declarations. The way to distinguish is that the version
- parameter will be NULL for text declarations. The encoding
- parameter may be NULL for XML declarations. The standalone
- parameter will be -1, 0, or 1 indicating respectively that there
- was no standalone parameter in the declaration, that it was given
- as no, or that it was given as yes.
-*/
-typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData,
- const XML_Char *version,
- const XML_Char *encoding,
- int standalone);
-
-XMLPARSEAPI(void)
-XML_SetXmlDeclHandler(XML_Parser parser,
- XML_XmlDeclHandler xmldecl);
-
-
-typedef struct {
- void *(*malloc_fcn)(size_t size);
- void *(*realloc_fcn)(void *ptr, size_t size);
- void (*free_fcn)(void *ptr);
-} XML_Memory_Handling_Suite;
-
-/* Constructs a new parser; encoding is the encoding specified by the
- external protocol or NULL if there is none specified.
-*/
-XMLPARSEAPI(XML_Parser)
-XML_ParserCreate(const XML_Char *encoding);
-
-/* Constructs a new parser and namespace processor. Element type
- names and attribute names that belong to a namespace will be
- expanded; unprefixed attribute names are never expanded; unprefixed
- element type names are expanded only if there is a default
- namespace. The expanded name is the concatenation of the namespace
- URI, the namespace separator character, and the local part of the
- name. If the namespace separator is '\0' then the namespace URI
- and the local part will be concatenated without any separator.
- It is a programming error to use the separator '\0' with namespace
- triplets (see XML_SetReturnNSTriplet).
-*/
-XMLPARSEAPI(XML_Parser)
-XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
-
-
-/* Constructs a new parser using the memory management suite referred to
- by memsuite. If memsuite is NULL, then use the standard library memory
- suite. If namespaceSeparator is non-NULL it creates a parser with
- namespace processing as described above. The character pointed at
- will serve as the namespace separator.
-
- All further memory operations used for the created parser will come from
- the given suite.
-*/
-XMLPARSEAPI(XML_Parser)
-XML_ParserCreate_MM(const XML_Char *encoding,
- const XML_Memory_Handling_Suite *memsuite,
- const XML_Char *namespaceSeparator);
-
-/* Prepare a parser object to be re-used. This is particularly
- valuable when memory allocation overhead is disproportionatly high,
- such as when a large number of small documnents need to be parsed.
- All handlers are cleared from the parser, except for the
- unknownEncodingHandler. The parser's external state is re-initialized
- except for the values of ns and ns_triplets.
-
- Added in Expat 1.95.3.
-*/
-XMLPARSEAPI(XML_Bool)
-XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
-
-/* atts is array of name/value pairs, terminated by 0;
- names and values are 0 terminated.
-*/
-typedef void (XMLCALL *XML_StartElementHandler) (void *userData,
- const XML_Char *name,
- const XML_Char **atts);
-
-typedef void (XMLCALL *XML_EndElementHandler) (void *userData,
- const XML_Char *name);
-
-
-/* s is not 0 terminated. */
-typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData,
- const XML_Char *s,
- int len);
-
-/* target and data are 0 terminated */
-typedef void (XMLCALL *XML_ProcessingInstructionHandler) (
- void *userData,
- const XML_Char *target,
- const XML_Char *data);
-
-/* data is 0 terminated */
-typedef void (XMLCALL *XML_CommentHandler) (void *userData,
- const XML_Char *data);
-
-typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData);
-typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
-
-/* This is called for any characters in the XML document for which
- there is no applicable handler. This includes both characters that
- are part of markup which is of a kind that is not reported
- (comments, markup declarations), or characters that are part of a
- construct which could be reported but for which no handler has been
- supplied. The characters are passed exactly as they were in the XML
- document except that they will be encoded in UTF-8 or UTF-16.
- Line boundaries are not normalized. Note that a byte order mark
- character is not passed to the default handler. There are no
- guarantees about how characters are divided between calls to the
- default handler: for example, a comment might be split between
- multiple calls.
-*/
-typedef void (XMLCALL *XML_DefaultHandler) (void *userData,
- const XML_Char *s,
- int len);
-
-/* This is called for the start of the DOCTYPE declaration, before
- any DTD or internal subset is parsed.
-*/
-typedef void (XMLCALL *XML_StartDoctypeDeclHandler) (
- void *userData,
- const XML_Char *doctypeName,
- const XML_Char *sysid,
- const XML_Char *pubid,
- int has_internal_subset);
-
-/* This is called for the start of the DOCTYPE declaration when the
- closing > is encountered, but after processing any external
- subset.
-*/
-typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
-
-/* This is called for entity declarations. The is_parameter_entity
- argument will be non-zero if the entity is a parameter entity, zero
- otherwise.
-
- For internal entities (), value will
- be non-NULL and systemId, publicID, and notationName will be NULL.
- The value string is NOT nul-terminated; the length is provided in
- the value_length argument. Since it is legal to have zero-length
- values, do not use this argument to test for internal entities.
-
- For external entities, value will be NULL and systemId will be
- non-NULL. The publicId argument will be NULL unless a public
- identifier was provided. The notationName argument will have a
- non-NULL value only for unparsed entity declarations.
-
- Note that is_parameter_entity can't be changed to XML_Bool, since
- that would break binary compatibility.
-*/
-typedef void (XMLCALL *XML_EntityDeclHandler) (
- void *userData,
- const XML_Char *entityName,
- int is_parameter_entity,
- const XML_Char *value,
- int value_length,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId,
- const XML_Char *notationName);
-
-XMLPARSEAPI(void)
-XML_SetEntityDeclHandler(XML_Parser parser,
- XML_EntityDeclHandler handler);
-
-/* OBSOLETE -- OBSOLETE -- OBSOLETE
- This handler has been superseded by the EntityDeclHandler above.
- It is provided here for backward compatibility.
-
- This is called for a declaration of an unparsed (NDATA) entity.
- The base argument is whatever was set by XML_SetBase. The
- entityName, systemId and notationName arguments will never be
- NULL. The other arguments may be.
-*/
-typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (
- void *userData,
- const XML_Char *entityName,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId,
- const XML_Char *notationName);
-
-/* This is called for a declaration of notation. The base argument is
- whatever was set by XML_SetBase. The notationName will never be
- NULL. The other arguments can be.
-*/
-typedef void (XMLCALL *XML_NotationDeclHandler) (
- void *userData,
- const XML_Char *notationName,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId);
-
-/* When namespace processing is enabled, these are called once for
- each namespace declaration. The call to the start and end element
- handlers occur between the calls to the start and end namespace
- declaration handlers. For an xmlns attribute, prefix will be
- NULL. For an xmlns="" attribute, uri will be NULL.
-*/
-typedef void (XMLCALL *XML_StartNamespaceDeclHandler) (
- void *userData,
- const XML_Char *prefix,
- const XML_Char *uri);
-
-typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
- void *userData,
- const XML_Char *prefix);
-
-/* This is called if the document is not standalone, that is, it has an
- external subset or a reference to a parameter entity, but does not
- have standalone="yes". If this handler returns XML_STATUS_ERROR,
- then processing will not continue, and the parser will return a
- XML_ERROR_NOT_STANDALONE error.
- If parameter entity parsing is enabled, then in addition to the
- conditions above this handler will only be called if the referenced
- entity was actually read.
-*/
-typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
-
-/* This is called for a reference to an external parsed general
- entity. The referenced entity is not automatically parsed. The
- application can parse it immediately or later using
- XML_ExternalEntityParserCreate.
-
- The parser argument is the parser parsing the entity containing the
- reference; it can be passed as the parser argument to
- XML_ExternalEntityParserCreate. The systemId argument is the
- system identifier as specified in the entity declaration; it will
- not be NULL.
-
- The base argument is the system identifier that should be used as
- the base for resolving systemId if systemId was relative; this is
- set by XML_SetBase; it may be NULL.
-
- The publicId argument is the public identifier as specified in the
- entity declaration, or NULL if none was specified; the whitespace
- in the public identifier will have been normalized as required by
- the XML spec.
-
- The context argument specifies the parsing context in the format
- expected by the context argument to XML_ExternalEntityParserCreate;
- context is valid only until the handler returns, so if the
- referenced entity is to be parsed later, it must be copied.
- context is NULL only when the entity is a parameter entity.
-
- The handler should return XML_STATUS_ERROR if processing should not
- continue because of a fatal error in the handling of the external
- entity. In this case the calling parser will return an
- XML_ERROR_EXTERNAL_ENTITY_HANDLING error.
-
- Note that unlike other handlers the first argument is the parser,
- not userData.
-*/
-typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
- XML_Parser parser,
- const XML_Char *context,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId);
-
-/* This is called in two situations:
- 1) An entity reference is encountered for which no declaration
- has been read *and* this is not an error.
- 2) An internal entity reference is read, but not expanded, because
- XML_SetDefaultHandler has been called.
- Note: skipped parameter entities in declarations and skipped general
- entities in attribute values cannot be reported, because
- the event would be out of sync with the reporting of the
- declarations or attribute values
-*/
-typedef void (XMLCALL *XML_SkippedEntityHandler) (
- void *userData,
- const XML_Char *entityName,
- int is_parameter_entity);
-
-/* This structure is filled in by the XML_UnknownEncodingHandler to
- provide information to the parser about encodings that are unknown
- to the parser.
-
- The map[b] member gives information about byte sequences whose
- first byte is b.
-
- If map[b] is c where c is >= 0, then b by itself encodes the
- Unicode scalar value c.
-
- If map[b] is -1, then the byte sequence is malformed.
-
- If map[b] is -n, where n >= 2, then b is the first byte of an
- n-byte sequence that encodes a single Unicode scalar value.
-
- The data member will be passed as the first argument to the convert
- function.
-
- The convert function is used to convert multibyte sequences; s will
- point to a n-byte sequence where map[(unsigned char)*s] == -n. The
- convert function must return the Unicode scalar value represented
- by this byte sequence or -1 if the byte sequence is malformed.
-
- The convert function may be NULL if the encoding is a single-byte
- encoding, that is if map[b] >= -1 for all bytes b.
-
- When the parser is finished with the encoding, then if release is
- not NULL, it will call release passing it the data member; once
- release has been called, the convert function will not be called
- again.
-
- Expat places certain restrictions on the encodings that are supported
- using this mechanism.
-
- 1. Every ASCII character that can appear in a well-formed XML document,
- other than the characters
-
- $@\^`{}~
-
- must be represented by a single byte, and that byte must be the
- same byte that represents that character in ASCII.
-
- 2. No character may require more than 4 bytes to encode.
-
- 3. All characters encoded must have Unicode scalar values <=
- 0xFFFF, (i.e., characters that would be encoded by surrogates in
- UTF-16 are not allowed). Note that this restriction doesn't
- apply to the built-in support for UTF-8 and UTF-16.
-
- 4. No Unicode character may be encoded by more than one distinct
- sequence of bytes.
-*/
-typedef struct {
- int map[256];
- void *data;
- int (XMLCALL *convert)(void *data, const char *s);
- void (XMLCALL *release)(void *data);
-} XML_Encoding;
-
-/* This is called for an encoding that is unknown to the parser.
-
- The encodingHandlerData argument is that which was passed as the
- second argument to XML_SetUnknownEncodingHandler.
-
- The name argument gives the name of the encoding as specified in
- the encoding declaration.
-
- If the callback can provide information about the encoding, it must
- fill in the XML_Encoding structure, and return XML_STATUS_OK.
- Otherwise it must return XML_STATUS_ERROR.
-
- If info does not describe a suitable encoding, then the parser will
- return an XML_UNKNOWN_ENCODING error.
-*/
-typedef int (XMLCALL *XML_UnknownEncodingHandler) (
- void *encodingHandlerData,
- const XML_Char *name,
- XML_Encoding *info);
-
-XMLPARSEAPI(void)
-XML_SetElementHandler(XML_Parser parser,
- XML_StartElementHandler start,
- XML_EndElementHandler end);
-
-XMLPARSEAPI(void)
-XML_SetStartElementHandler(XML_Parser parser,
- XML_StartElementHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetEndElementHandler(XML_Parser parser,
- XML_EndElementHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetCharacterDataHandler(XML_Parser parser,
- XML_CharacterDataHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetProcessingInstructionHandler(XML_Parser parser,
- XML_ProcessingInstructionHandler handler);
-XMLPARSEAPI(void)
-XML_SetCommentHandler(XML_Parser parser,
- XML_CommentHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetCdataSectionHandler(XML_Parser parser,
- XML_StartCdataSectionHandler start,
- XML_EndCdataSectionHandler end);
-
-XMLPARSEAPI(void)
-XML_SetStartCdataSectionHandler(XML_Parser parser,
- XML_StartCdataSectionHandler start);
-
-XMLPARSEAPI(void)
-XML_SetEndCdataSectionHandler(XML_Parser parser,
- XML_EndCdataSectionHandler end);
-
-/* This sets the default handler and also inhibits expansion of
- internal entities. These entity references will be passed to the
- default handler, or to the skipped entity handler, if one is set.
-*/
-XMLPARSEAPI(void)
-XML_SetDefaultHandler(XML_Parser parser,
- XML_DefaultHandler handler);
-
-/* This sets the default handler but does not inhibit expansion of
- internal entities. The entity reference will not be passed to the
- default handler.
-*/
-XMLPARSEAPI(void)
-XML_SetDefaultHandlerExpand(XML_Parser parser,
- XML_DefaultHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetDoctypeDeclHandler(XML_Parser parser,
- XML_StartDoctypeDeclHandler start,
- XML_EndDoctypeDeclHandler end);
-
-XMLPARSEAPI(void)
-XML_SetStartDoctypeDeclHandler(XML_Parser parser,
- XML_StartDoctypeDeclHandler start);
-
-XMLPARSEAPI(void)
-XML_SetEndDoctypeDeclHandler(XML_Parser parser,
- XML_EndDoctypeDeclHandler end);
-
-XMLPARSEAPI(void)
-XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
- XML_UnparsedEntityDeclHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetNotationDeclHandler(XML_Parser parser,
- XML_NotationDeclHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetNamespaceDeclHandler(XML_Parser parser,
- XML_StartNamespaceDeclHandler start,
- XML_EndNamespaceDeclHandler end);
-
-XMLPARSEAPI(void)
-XML_SetStartNamespaceDeclHandler(XML_Parser parser,
- XML_StartNamespaceDeclHandler start);
-
-XMLPARSEAPI(void)
-XML_SetEndNamespaceDeclHandler(XML_Parser parser,
- XML_EndNamespaceDeclHandler end);
-
-XMLPARSEAPI(void)
-XML_SetNotStandaloneHandler(XML_Parser parser,
- XML_NotStandaloneHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetExternalEntityRefHandler(XML_Parser parser,
- XML_ExternalEntityRefHandler handler);
-
-/* If a non-NULL value for arg is specified here, then it will be
- passed as the first argument to the external entity ref handler
- instead of the parser object.
-*/
-XMLPARSEAPI(void)
-XML_SetExternalEntityRefHandlerArg(XML_Parser parser,
- void *arg);
-
-XMLPARSEAPI(void)
-XML_SetSkippedEntityHandler(XML_Parser parser,
- XML_SkippedEntityHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetUnknownEncodingHandler(XML_Parser parser,
- XML_UnknownEncodingHandler handler,
- void *encodingHandlerData);
-
-/* This can be called within a handler for a start element, end
- element, processing instruction or character data. It causes the
- corresponding markup to be passed to the default handler.
-*/
-XMLPARSEAPI(void)
-XML_DefaultCurrent(XML_Parser parser);
-
-/* If do_nst is non-zero, and namespace processing is in effect, and
- a name has a prefix (i.e. an explicit namespace qualifier) then
- that name is returned as a triplet in a single string separated by
- the separator character specified when the parser was created: URI
- + sep + local_name + sep + prefix.
-
- If do_nst is zero, then namespace information is returned in the
- default manner (URI + sep + local_name) whether or not the name
- has a prefix.
-
- Note: Calling XML_SetReturnNSTriplet after XML_Parse or
- XML_ParseBuffer has no effect.
-*/
-
-XMLPARSEAPI(void)
-XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);
-
-/* This value is passed as the userData argument to callbacks. */
-XMLPARSEAPI(void)
-XML_SetUserData(XML_Parser parser, void *userData);
-
-/* Returns the last value set by XML_SetUserData or NULL. */
-#define XML_GetUserData(parser) (*(void **)(parser))
-
-/* This is equivalent to supplying an encoding argument to
- XML_ParserCreate. On success XML_SetEncoding returns non-zero,
- zero otherwise.
- Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer
- has no effect and returns XML_STATUS_ERROR.
-*/
-XMLPARSEAPI(enum XML_Status)
-XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
-
-/* If this function is called, then the parser will be passed as the
- first argument to callbacks instead of userData. The userData will
- still be accessible using XML_GetUserData.
-*/
-XMLPARSEAPI(void)
-XML_UseParserAsHandlerArg(XML_Parser parser);
-
-/* If useDTD == XML_TRUE is passed to this function, then the parser
- will assume that there is an external subset, even if none is
- specified in the document. In such a case the parser will call the
- externalEntityRefHandler with a value of NULL for the systemId
- argument (the publicId and context arguments will be NULL as well).
- Note: For the purpose of checking WFC: Entity Declared, passing
- useDTD == XML_TRUE will make the parser behave as if the document
- had a DTD with an external subset.
- Note: If this function is called, then this must be done before
- the first call to XML_Parse or XML_ParseBuffer, since it will
- have no effect after that. Returns
- XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
- Note: If the document does not have a DOCTYPE declaration at all,
- then startDoctypeDeclHandler and endDoctypeDeclHandler will not
- be called, despite an external subset being parsed.
- Note: If XML_DTD is not defined when Expat is compiled, returns
- XML_ERROR_FEATURE_REQUIRES_XML_DTD.
-*/
-XMLPARSEAPI(enum XML_Error)
-XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
-
-
-/* Sets the base to be used for resolving relative URIs in system
- identifiers in declarations. Resolving relative identifiers is
- left to the application: this value will be passed through as the
- base argument to the XML_ExternalEntityRefHandler,
- XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base
- argument will be copied. Returns XML_STATUS_ERROR if out of memory,
- XML_STATUS_OK otherwise.
-*/
-XMLPARSEAPI(enum XML_Status)
-XML_SetBase(XML_Parser parser, const XML_Char *base);
-
-XMLPARSEAPI(const XML_Char *)
-XML_GetBase(XML_Parser parser);
-
-/* Returns the number of the attribute/value pairs passed in last call
- to the XML_StartElementHandler that were specified in the start-tag
- rather than defaulted. Each attribute/value pair counts as 2; thus
- this correspondds to an index into the atts array passed to the
- XML_StartElementHandler.
-*/
-XMLPARSEAPI(int)
-XML_GetSpecifiedAttributeCount(XML_Parser parser);
-
-/* Returns the index of the ID attribute passed in the last call to
- XML_StartElementHandler, or -1 if there is no ID attribute. Each
- attribute/value pair counts as 2; thus this correspondds to an
- index into the atts array passed to the XML_StartElementHandler.
-*/
-XMLPARSEAPI(int)
-XML_GetIdAttributeIndex(XML_Parser parser);
-
-#ifdef XML_ATTR_INFO
-/* Source file byte offsets for the start and end of attribute names and values.
- The value indices are exclusive of surrounding quotes; thus in a UTF-8 source
- file an attribute value of "blah" will yield:
- info->valueEnd - info->valueStart = 4 bytes.
-*/
-typedef struct {
- XML_Index nameStart; /* Offset to beginning of the attribute name. */
- XML_Index nameEnd; /* Offset after the attribute name's last byte. */
- XML_Index valueStart; /* Offset to beginning of the attribute value. */
- XML_Index valueEnd; /* Offset after the attribute value's last byte. */
-} XML_AttrInfo;
-
-/* Returns an array of XML_AttrInfo structures for the attribute/value pairs
- passed in last call to the XML_StartElementHandler that were specified
- in the start-tag rather than defaulted. Each attribute/value pair counts
- as 1; thus the number of entries in the array is
- XML_GetSpecifiedAttributeCount(parser) / 2.
-*/
-XMLPARSEAPI(const XML_AttrInfo *)
-XML_GetAttributeInfo(XML_Parser parser);
-#endif
-
-/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
- detected. The last call to XML_Parse must have isFinal true; len
- may be zero for this call (or any other).
-
- Though the return values for these functions has always been
- described as a Boolean value, the implementation, at least for the
- 1.95.x series, has always returned exactly one of the XML_Status
- values.
-*/
-XMLPARSEAPI(enum XML_Status)
-XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
-
-XMLPARSEAPI(void *)
-XML_GetBuffer(XML_Parser parser, int len);
-
-XMLPARSEAPI(enum XML_Status)
-XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
-
-/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return.
- Must be called from within a call-back handler, except when aborting
- (resumable = 0) an already suspended parser. Some call-backs may
- still follow because they would otherwise get lost. Examples:
- - endElementHandler() for empty elements when stopped in
- startElementHandler(),
- - endNameSpaceDeclHandler() when stopped in endElementHandler(),
- and possibly others.
-
- Can be called from most handlers, including DTD related call-backs,
- except when parsing an external parameter entity and resumable != 0.
- Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise.
- Possible error codes:
- - XML_ERROR_SUSPENDED: when suspending an already suspended parser.
- - XML_ERROR_FINISHED: when the parser has already finished.
- - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE.
-
- When resumable != 0 (true) then parsing is suspended, that is,
- XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED.
- Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer()
- return XML_STATUS_ERROR with error code XML_ERROR_ABORTED.
-
- *Note*:
- This will be applied to the current parser instance only, that is, if
- there is a parent parser then it will continue parsing when the
- externalEntityRefHandler() returns. It is up to the implementation of
- the externalEntityRefHandler() to call XML_StopParser() on the parent
- parser (recursively), if one wants to stop parsing altogether.
-
- When suspended, parsing can be resumed by calling XML_ResumeParser().
-*/
-XMLPARSEAPI(enum XML_Status)
-XML_StopParser(XML_Parser parser, XML_Bool resumable);
-
-/* Resumes parsing after it has been suspended with XML_StopParser().
- Must not be called from within a handler call-back. Returns same
- status codes as XML_Parse() or XML_ParseBuffer().
- Additional error code XML_ERROR_NOT_SUSPENDED possible.
-
- *Note*:
- This must be called on the most deeply nested child parser instance
- first, and on its parent parser only after the child parser has finished,
- to be applied recursively until the document entity's parser is restarted.
- That is, the parent parser will not resume by itself and it is up to the
- application to call XML_ResumeParser() on it at the appropriate moment.
-*/
-XMLPARSEAPI(enum XML_Status)
-XML_ResumeParser(XML_Parser parser);
-
-enum XML_Parsing {
- XML_INITIALIZED,
- XML_PARSING,
- XML_FINISHED,
- XML_SUSPENDED
-};
-
-typedef struct {
- enum XML_Parsing parsing;
- XML_Bool finalBuffer;
-} XML_ParsingStatus;
-
-/* Returns status of parser with respect to being initialized, parsing,
- finished, or suspended and processing the final buffer.
- XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus,
- XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED
-*/
-XMLPARSEAPI(void)
-XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status);
-
-/* Creates an XML_Parser object that can parse an external general
- entity; context is a '\0'-terminated string specifying the parse
- context; encoding is a '\0'-terminated string giving the name of
- the externally specified encoding, or NULL if there is no
- externally specified encoding. The context string consists of a
- sequence of tokens separated by formfeeds (\f); a token consisting
- of a name specifies that the general entity of the name is open; a
- token of the form prefix=uri specifies the namespace for a
- particular prefix; a token of the form =uri specifies the default
- namespace. This can be called at any point after the first call to
- an ExternalEntityRefHandler so longer as the parser has not yet
- been freed. The new parser is completely independent and may
- safely be used in a separate thread. The handlers and userData are
- initialized from the parser argument. Returns NULL if out of memory.
- Otherwise returns a new XML_Parser object.
-*/
-XMLPARSEAPI(XML_Parser)
-XML_ExternalEntityParserCreate(XML_Parser parser,
- const XML_Char *context,
- const XML_Char *encoding);
-
-enum XML_ParamEntityParsing {
- XML_PARAM_ENTITY_PARSING_NEVER,
- XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
- XML_PARAM_ENTITY_PARSING_ALWAYS
-};
-
-/* Controls parsing of parameter entities (including the external DTD
- subset). If parsing of parameter entities is enabled, then
- references to external parameter entities (including the external
- DTD subset) will be passed to the handler set with
- XML_SetExternalEntityRefHandler. The context passed will be 0.
-
- Unlike external general entities, external parameter entities can
- only be parsed synchronously. If the external parameter entity is
- to be parsed, it must be parsed during the call to the external
- entity ref handler: the complete sequence of
- XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and
- XML_ParserFree calls must be made during this call. After
- XML_ExternalEntityParserCreate has been called to create the parser
- for the external parameter entity (context must be 0 for this
- call), it is illegal to make any calls on the old parser until
- XML_ParserFree has been called on the newly created parser.
- If the library has been compiled without support for parameter
- entity parsing (ie without XML_DTD being defined), then
- XML_SetParamEntityParsing will return 0 if parsing of parameter
- entities is requested; otherwise it will return non-zero.
- Note: If XML_SetParamEntityParsing is called after XML_Parse or
- XML_ParseBuffer, then it has no effect and will always return 0.
-*/
-XMLPARSEAPI(int)
-XML_SetParamEntityParsing(XML_Parser parser,
- enum XML_ParamEntityParsing parsing);
-
-/* Sets the hash salt to use for internal hash calculations.
- Helps in preventing DoS attacks based on predicting hash
- function behavior. This must be called before parsing is started.
- Returns 1 if successful, 0 when called after parsing has started.
-*/
-XMLPARSEAPI(int)
-XML_SetHashSalt(XML_Parser parser,
- unsigned long hash_salt);
-
-/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
- XML_GetErrorCode returns information about the error.
-*/
-XMLPARSEAPI(enum XML_Error)
-XML_GetErrorCode(XML_Parser parser);
-
-/* These functions return information about the current parse
- location. They may be called from any callback called to report
- some parse event; in this case the location is the location of the
- first of the sequence of characters that generated the event. When
- called from callbacks generated by declarations in the document
- prologue, the location identified isn't as neatly defined, but will
- be within the relevant markup. When called outside of the callback
- functions, the position indicated will be just past the last parse
- event (regardless of whether there was an associated callback).
-
- They may also be called after returning from a call to XML_Parse
- or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then
- the location is the location of the character at which the error
- was detected; otherwise the location is the location of the last
- parse event, as described above.
-*/
-XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
-XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
-XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);
-
-/* Return the number of bytes in the current event.
- Returns 0 if the event is in an internal entity.
-*/
-XMLPARSEAPI(int)
-XML_GetCurrentByteCount(XML_Parser parser);
-
-/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
- the integer pointed to by offset to the offset within this buffer
- of the current parse position, and sets the integer pointed to by size
- to the size of this buffer (the number of input bytes). Otherwise
- returns a NULL pointer. Also returns a NULL pointer if a parse isn't
- active.
-
- NOTE: The character pointer returned should not be used outside
- the handler that makes the call.
-*/
-XMLPARSEAPI(const char *)
-XML_GetInputContext(XML_Parser parser,
- int *offset,
- int *size);
-
-/* For backwards compatibility with previous versions. */
-#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
-#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
-#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
-
-/* Frees the content model passed to the element declaration handler */
-XMLPARSEAPI(void)
-XML_FreeContentModel(XML_Parser parser, XML_Content *model);
-
-/* Exposing the memory handling functions used in Expat */
-XMLPARSEAPI(void *)
-XML_ATTR_MALLOC
-XML_ATTR_ALLOC_SIZE(2)
-XML_MemMalloc(XML_Parser parser, size_t size);
-
-XMLPARSEAPI(void *)
-XML_ATTR_ALLOC_SIZE(3)
-XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
-
-XMLPARSEAPI(void)
-XML_MemFree(XML_Parser parser, void *ptr);
-
-/* Frees memory used by the parser. */
-XMLPARSEAPI(void)
-XML_ParserFree(XML_Parser parser);
-
-/* Returns a string describing the error. */
-XMLPARSEAPI(const XML_LChar *)
-XML_ErrorString(enum XML_Error code);
-
-/* Return a string containing the version number of this expat */
-XMLPARSEAPI(const XML_LChar *)
-XML_ExpatVersion(void);
-
-typedef struct {
- int major;
- int minor;
- int micro;
-} XML_Expat_Version;
-
-/* Return an XML_Expat_Version structure containing numeric version
- number information for this version of expat.
-*/
-XMLPARSEAPI(XML_Expat_Version)
-XML_ExpatVersionInfo(void);
-
-/* Added in Expat 1.95.5. */
-enum XML_FeatureEnum {
- XML_FEATURE_END = 0,
- XML_FEATURE_UNICODE,
- XML_FEATURE_UNICODE_WCHAR_T,
- XML_FEATURE_DTD,
- XML_FEATURE_CONTEXT_BYTES,
- XML_FEATURE_MIN_SIZE,
- XML_FEATURE_SIZEOF_XML_CHAR,
- XML_FEATURE_SIZEOF_XML_LCHAR,
- XML_FEATURE_NS,
- XML_FEATURE_LARGE_SIZE,
- XML_FEATURE_ATTR_INFO
- /* Additional features must be added to the end of this enum. */
-};
-
-typedef struct {
- enum XML_FeatureEnum feature;
- const XML_LChar *name;
- long int value;
-} XML_Feature;
-
-XMLPARSEAPI(const XML_Feature *)
-XML_GetFeatureList(void);
-
-
-/* Expat follows the semantic versioning convention.
- See http://semver.org.
-*/
-#define XML_MAJOR_VERSION 2
-#define XML_MINOR_VERSION 2
-#define XML_MICRO_VERSION 0
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not Expat_INCLUDED */
diff --git a/components/expat/include/expat/expat_external.h b/components/expat/include/expat/expat_external.h
deleted file mode 100644
index aa08a2f84c..0000000000
--- a/components/expat/include/expat/expat_external.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#ifndef Expat_External_INCLUDED
-#define Expat_External_INCLUDED 1
-
-/* External API definitions */
-
-#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
-#define XML_USE_MSC_EXTENSIONS 1
-#endif
-
-/* Expat tries very hard to make the API boundary very specifically
- defined. There are two macros defined to control this boundary;
- each of these can be defined before including this header to
- achieve some different behavior, but doing so it not recommended or
- tested frequently.
-
- XMLCALL - The calling convention to use for all calls across the
- "library boundary." This will default to cdecl, and
- try really hard to tell the compiler that's what we
- want.
-
- XMLIMPORT - Whatever magic is needed to note that a function is
- to be imported from a dynamically loaded library
- (.dll, .so, or .sl, depending on your platform).
-
- The XMLCALL macro was added in Expat 1.95.7. The only one which is
- expected to be directly useful in client code is XMLCALL.
-
- Note that on at least some Unix versions, the Expat library must be
- compiled with the cdecl calling convention as the default since
- system headers may assume the cdecl convention.
-*/
-#ifndef XMLCALL
-#if defined(_MSC_VER)
-#define XMLCALL __cdecl
-#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
-#define XMLCALL __attribute__((cdecl))
-#else
-/* For any platform which uses this definition and supports more than
- one calling convention, we need to extend this definition to
- declare the convention used on that platform, if it's possible to
- do so.
-
- If this is the case for your platform, please file a bug report
- with information on how to identify your platform via the C
- pre-processor and how to specify the same calling convention as the
- platform's malloc() implementation.
-*/
-#define XMLCALL
-#endif
-#endif /* not defined XMLCALL */
-
-
-#if !defined(XML_STATIC) && !defined(XMLIMPORT)
-#ifndef XML_BUILDING_EXPAT
-/* using Expat from an application */
-
-#ifdef XML_USE_MSC_EXTENSIONS
-#define XMLIMPORT __declspec(dllimport)
-#endif
-
-#endif
-#endif /* not defined XML_STATIC */
-
-#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)
-#define XMLIMPORT __attribute__ ((visibility ("default")))
-#endif
-
-/* If we didn't define it above, define it away: */
-#ifndef XMLIMPORT
-#define XMLIMPORT
-#endif
-
-#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
-#define XML_ATTR_MALLOC __attribute__((__malloc__))
-#else
-#define XML_ATTR_MALLOC
-#endif
-
-#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
-#define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
-#else
-#define XML_ATTR_ALLOC_SIZE(x)
-#endif
-
-#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef XML_UNICODE_WCHAR_T
-#define XML_UNICODE
-#endif
-
-#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
-#ifdef XML_UNICODE_WCHAR_T
-typedef wchar_t XML_Char;
-typedef wchar_t XML_LChar;
-#else
-typedef unsigned short XML_Char;
-typedef char XML_LChar;
-#endif /* XML_UNICODE_WCHAR_T */
-#else /* Information is UTF-8 encoded. */
-typedef char XML_Char;
-typedef char XML_LChar;
-#endif /* XML_UNICODE */
-
-#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
-#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
-typedef __int64 XML_Index;
-typedef unsigned __int64 XML_Size;
-#else
-typedef long long XML_Index;
-typedef unsigned long long XML_Size;
-#endif
-#else
-typedef long XML_Index;
-typedef unsigned long XML_Size;
-#endif /* XML_LARGE_SIZE */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not Expat_External_INCLUDED */
diff --git a/components/expat/include/expat/iasciitab.h b/components/expat/include/expat/iasciitab.h
deleted file mode 100644
index 24a1d5ccc9..0000000000
--- a/components/expat/include/expat/iasciitab.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
-/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
-/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
-/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
-/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
-/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
-/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
-/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
-/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
-/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
-/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
-/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/components/expat/include/expat/internal.h b/components/expat/include/expat/internal.h
deleted file mode 100644
index 94cb98e15c..0000000000
--- a/components/expat/include/expat/internal.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* internal.h
-
- Internal definitions used by Expat. This is not needed to compile
- client code.
-
- The following calling convention macros are defined for frequently
- called functions:
-
- FASTCALL - Used for those internal functions that have a simple
- body and a low number of arguments and local variables.
-
- PTRCALL - Used for functions called though function pointers.
-
- PTRFASTCALL - Like PTRCALL, but for low number of arguments.
-
- inline - Used for selected internal functions for which inlining
- may improve performance on some platforms.
-
- Note: Use of these macros is based on judgement, not hard rules,
- and therefore subject to change.
-*/
-
-#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)
-/* We'll use this version by default only where we know it helps.
-
- regparm() generates warnings on Solaris boxes. See SF bug #692878.
-
- Instability reported with egcs on a RedHat Linux 7.3.
- Let's comment out:
- #define FASTCALL __attribute__((stdcall, regparm(3)))
- and let's try this:
-*/
-#define FASTCALL __attribute__((regparm(3)))
-#define PTRFASTCALL __attribute__((regparm(3)))
-#endif
-
-/* Using __fastcall seems to have an unexpected negative effect under
- MS VC++, especially for function pointers, so we won't use it for
- now on that platform. It may be reconsidered for a future release
- if it can be made more effective.
- Likely reason: __fastcall on Windows is like stdcall, therefore
- the compiler cannot perform stack optimizations for call clusters.
-*/
-
-/* Make sure all of these are defined if they aren't already. */
-
-#ifndef FASTCALL
-#define FASTCALL
-#endif
-
-#ifndef PTRCALL
-#define PTRCALL
-#endif
-
-#ifndef PTRFASTCALL
-#define PTRFASTCALL
-#endif
-
-#ifndef XML_MIN_SIZE
-#if !defined(__cplusplus) && !defined(inline)
-#ifdef __GNUC__
-#define inline __inline
-#endif /* __GNUC__ */
-#endif
-#endif /* XML_MIN_SIZE */
-
-#ifdef __cplusplus
-#define inline inline
-#else
-#ifndef inline
-#define inline
-#endif
-#endif
-
-#ifndef UNUSED_P
-# ifdef __GNUC__
-# define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))
-# else
-# define UNUSED_P(p) UNUSED_ ## p
-# endif
-#endif
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-void
-align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef);
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/components/expat/include/expat/latin1tab.h b/components/expat/include/expat/latin1tab.h
deleted file mode 100644
index 53c25d76b2..0000000000
--- a/components/expat/include/expat/latin1tab.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
-/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
-/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
-/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
diff --git a/components/expat/include/expat/nametab.h b/components/expat/include/expat/nametab.h
deleted file mode 100644
index b05e62c77a..0000000000
--- a/components/expat/include/expat/nametab.h
+++ /dev/null
@@ -1,150 +0,0 @@
-static const unsigned namingBitmap[] = {
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
-0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
-0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
-0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
-0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
-0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
-0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
-0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
-0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
-0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
-0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
-0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
-0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
-0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
-0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
-0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
-0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
-0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
-0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
-0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
-0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
-0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
-0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
-0x40000000, 0xF580C900, 0x00000007, 0x02010800,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
-0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
-0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
-0x00000000, 0x00004C40, 0x00000000, 0x00000000,
-0x00000007, 0x00000000, 0x00000000, 0x00000000,
-0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
-0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
-0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
-0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
-0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
-0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
-0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
-0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
-0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
-0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
-0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
-0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
-0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
-0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
-0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
-0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
-0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
-0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
-0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
-0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
-0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
-0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
-0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
-0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
-0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
-0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
-0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
-0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
-};
-static const unsigned char nmstrtPages[] = {
-0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
-0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
-0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-static const unsigned char namePages[] = {
-0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
-0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
-0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
-0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
diff --git a/components/expat/include/expat/utf8tab.h b/components/expat/include/expat/utf8tab.h
deleted file mode 100644
index 7bb3e77603..0000000000
--- a/components/expat/include/expat/utf8tab.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-
-/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
-/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
diff --git a/components/expat/include/expat/xmlrole.h b/components/expat/include/expat/xmlrole.h
deleted file mode 100644
index 4dd9f06f97..0000000000
--- a/components/expat/include/expat/xmlrole.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#ifndef XmlRole_INCLUDED
-#define XmlRole_INCLUDED 1
-
-#ifdef __VMS
-/* 0 1 2 3 0 1 2 3
- 1234567890123456789012345678901 1234567890123456789012345678901 */
-#define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
-#endif
-
-#include "xmltok.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
- XML_ROLE_ERROR = -1,
- XML_ROLE_NONE = 0,
- XML_ROLE_XML_DECL,
- XML_ROLE_INSTANCE_START,
- XML_ROLE_DOCTYPE_NONE,
- XML_ROLE_DOCTYPE_NAME,
- XML_ROLE_DOCTYPE_SYSTEM_ID,
- XML_ROLE_DOCTYPE_PUBLIC_ID,
- XML_ROLE_DOCTYPE_INTERNAL_SUBSET,
- XML_ROLE_DOCTYPE_CLOSE,
- XML_ROLE_GENERAL_ENTITY_NAME,
- XML_ROLE_PARAM_ENTITY_NAME,
- XML_ROLE_ENTITY_NONE,
- XML_ROLE_ENTITY_VALUE,
- XML_ROLE_ENTITY_SYSTEM_ID,
- XML_ROLE_ENTITY_PUBLIC_ID,
- XML_ROLE_ENTITY_COMPLETE,
- XML_ROLE_ENTITY_NOTATION_NAME,
- XML_ROLE_NOTATION_NONE,
- XML_ROLE_NOTATION_NAME,
- XML_ROLE_NOTATION_SYSTEM_ID,
- XML_ROLE_NOTATION_NO_SYSTEM_ID,
- XML_ROLE_NOTATION_PUBLIC_ID,
- XML_ROLE_ATTRIBUTE_NAME,
- XML_ROLE_ATTRIBUTE_TYPE_CDATA,
- XML_ROLE_ATTRIBUTE_TYPE_ID,
- XML_ROLE_ATTRIBUTE_TYPE_IDREF,
- XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
- XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
- XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
- XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
- XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
- XML_ROLE_ATTRIBUTE_ENUM_VALUE,
- XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
- XML_ROLE_ATTLIST_NONE,
- XML_ROLE_ATTLIST_ELEMENT_NAME,
- XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
- XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
- XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
- XML_ROLE_FIXED_ATTRIBUTE_VALUE,
- XML_ROLE_ELEMENT_NONE,
- XML_ROLE_ELEMENT_NAME,
- XML_ROLE_CONTENT_ANY,
- XML_ROLE_CONTENT_EMPTY,
- XML_ROLE_CONTENT_PCDATA,
- XML_ROLE_GROUP_OPEN,
- XML_ROLE_GROUP_CLOSE,
- XML_ROLE_GROUP_CLOSE_REP,
- XML_ROLE_GROUP_CLOSE_OPT,
- XML_ROLE_GROUP_CLOSE_PLUS,
- XML_ROLE_GROUP_CHOICE,
- XML_ROLE_GROUP_SEQUENCE,
- XML_ROLE_CONTENT_ELEMENT,
- XML_ROLE_CONTENT_ELEMENT_REP,
- XML_ROLE_CONTENT_ELEMENT_OPT,
- XML_ROLE_CONTENT_ELEMENT_PLUS,
- XML_ROLE_PI,
- XML_ROLE_COMMENT,
-#ifdef XML_DTD
- XML_ROLE_TEXT_DECL,
- XML_ROLE_IGNORE_SECT,
- XML_ROLE_INNER_PARAM_ENTITY_REF,
-#endif /* XML_DTD */
- XML_ROLE_PARAM_ENTITY_REF
-};
-
-typedef struct prolog_state {
- int (PTRCALL *handler) (struct prolog_state *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc);
- unsigned level;
- int role_none;
-#ifdef XML_DTD
- unsigned includeLevel;
- int documentEntity;
- int inEntityValue;
-#endif /* XML_DTD */
-} PROLOG_STATE;
-
-void XmlPrologStateInit(PROLOG_STATE *);
-#ifdef XML_DTD
-void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
-#endif /* XML_DTD */
-
-#define XmlTokenRole(state, tok, ptr, end, enc) \
- (((state)->handler)(state, tok, ptr, end, enc))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not XmlRole_INCLUDED */
diff --git a/components/expat/include/expat/xmltok.h b/components/expat/include/expat/xmltok.h
deleted file mode 100644
index 752007e8b9..0000000000
--- a/components/expat/include/expat/xmltok.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#ifndef XmlTok_INCLUDED
-#define XmlTok_INCLUDED 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The following token may be returned by XmlContentTok */
-#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be
- start of illegal ]]> sequence */
-/* The following tokens may be returned by both XmlPrologTok and
- XmlContentTok.
-*/
-#define XML_TOK_NONE -4 /* The string to be scanned is empty */
-#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
- might be part of CRLF sequence */
-#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
-#define XML_TOK_PARTIAL -1 /* only part of a token */
-#define XML_TOK_INVALID 0
-
-/* The following tokens are returned by XmlContentTok; some are also
- returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.
-*/
-#define XML_TOK_START_TAG_WITH_ATTS 1
-#define XML_TOK_START_TAG_NO_ATTS 2
-#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag */
-#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
-#define XML_TOK_END_TAG 5
-#define XML_TOK_DATA_CHARS 6
-#define XML_TOK_DATA_NEWLINE 7
-#define XML_TOK_CDATA_SECT_OPEN 8
-#define XML_TOK_ENTITY_REF 9
-#define XML_TOK_CHAR_REF 10 /* numeric character reference */
-
-/* The following tokens may be returned by both XmlPrologTok and
- XmlContentTok.
-*/
-#define XML_TOK_PI 11 /* processing instruction */
-#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
-#define XML_TOK_COMMENT 13
-#define XML_TOK_BOM 14 /* Byte order mark */
-
-/* The following tokens are returned only by XmlPrologTok */
-#define XML_TOK_PROLOG_S 15
-#define XML_TOK_DECL_OPEN 16 /* */
-#define XML_TOK_NAME 18
-#define XML_TOK_NMTOKEN 19
-#define XML_TOK_POUND_NAME 20 /* #name */
-#define XML_TOK_OR 21 /* | */
-#define XML_TOK_PERCENT 22
-#define XML_TOK_OPEN_PAREN 23
-#define XML_TOK_CLOSE_PAREN 24
-#define XML_TOK_OPEN_BRACKET 25
-#define XML_TOK_CLOSE_BRACKET 26
-#define XML_TOK_LITERAL 27
-#define XML_TOK_PARAM_ENTITY_REF 28
-#define XML_TOK_INSTANCE_START 29
-
-/* The following occur only in element type declarations */
-#define XML_TOK_NAME_QUESTION 30 /* name? */
-#define XML_TOK_NAME_ASTERISK 31 /* name* */
-#define XML_TOK_NAME_PLUS 32 /* name+ */
-#define XML_TOK_COND_SECT_OPEN 33 /* */
-#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
-#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
-#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
-#define XML_TOK_COMMA 38
-
-/* The following token is returned only by XmlAttributeValueTok */
-#define XML_TOK_ATTRIBUTE_VALUE_S 39
-
-/* The following token is returned only by XmlCdataSectionTok */
-#define XML_TOK_CDATA_SECT_CLOSE 40
-
-/* With namespace processing this is returned by XmlPrologTok for a
- name with a colon.
-*/
-#define XML_TOK_PREFIXED_NAME 41
-
-#ifdef XML_DTD
-#define XML_TOK_IGNORE_SECT 42
-#endif /* XML_DTD */
-
-#ifdef XML_DTD
-#define XML_N_STATES 4
-#else /* not XML_DTD */
-#define XML_N_STATES 3
-#endif /* not XML_DTD */
-
-#define XML_PROLOG_STATE 0
-#define XML_CONTENT_STATE 1
-#define XML_CDATA_SECTION_STATE 2
-#ifdef XML_DTD
-#define XML_IGNORE_SECTION_STATE 3
-#endif /* XML_DTD */
-
-#define XML_N_LITERAL_TYPES 2
-#define XML_ATTRIBUTE_VALUE_LITERAL 0
-#define XML_ENTITY_VALUE_LITERAL 1
-
-/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
-#define XML_UTF8_ENCODE_MAX 4
-/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
-#define XML_UTF16_ENCODE_MAX 2
-
-typedef struct position {
- /* first line and first column are 0 not 1 */
- XML_Size lineNumber;
- XML_Size columnNumber;
-} POSITION;
-
-typedef struct {
- const char *name;
- const char *valuePtr;
- const char *valueEnd;
- char normalized;
-} ATTRIBUTE;
-
-struct encoding;
-typedef struct encoding ENCODING;
-
-typedef int (PTRCALL *SCANNER)(const ENCODING *,
- const char *,
- const char *,
- const char **);
-
-enum XML_Convert_Result {
- XML_CONVERT_COMPLETED = 0,
- XML_CONVERT_INPUT_INCOMPLETE = 1,
- XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining as well */
-};
-
-struct encoding {
- SCANNER scanners[XML_N_STATES];
- SCANNER literalScanners[XML_N_LITERAL_TYPES];
- int (PTRCALL *sameName)(const ENCODING *,
- const char *,
- const char *);
- int (PTRCALL *nameMatchesAscii)(const ENCODING *,
- const char *,
- const char *,
- const char *);
- int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
- const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
- int (PTRCALL *getAtts)(const ENCODING *enc,
- const char *ptr,
- int attsMax,
- ATTRIBUTE *atts);
- int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
- int (PTRCALL *predefinedEntityName)(const ENCODING *,
- const char *,
- const char *);
- void (PTRCALL *updatePosition)(const ENCODING *,
- const char *ptr,
- const char *end,
- POSITION *);
- int (PTRCALL *isPublicId)(const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr);
- enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc,
- const char **fromP,
- const char *fromLim,
- char **toP,
- const char *toLim);
- enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc,
- const char **fromP,
- const char *fromLim,
- unsigned short **toP,
- const unsigned short *toLim);
- int minBytesPerChar;
- char isUtf8;
- char isUtf16;
-};
-
-/* Scan the string starting at ptr until the end of the next complete
- token, but do not scan past eptr. Return an integer giving the
- type of token.
-
- Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
-
- Return XML_TOK_PARTIAL when the string does not contain a complete
- token; nextTokPtr will not be set.
-
- Return XML_TOK_INVALID when the string does not start a valid
- token; nextTokPtr will be set to point to the character which made
- the token invalid.
-
- Otherwise the string starts with a valid token; nextTokPtr will be
- set to point to the character following the end of that token.
-
- Each data character counts as a single token, but adjacent data
- characters may be returned together. Similarly for characters in
- the prolog outside literals, comments and processing instructions.
-*/
-
-
-#define XmlTok(enc, state, ptr, end, nextTokPtr) \
- (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
-
-#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
- XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
-
-#define XmlContentTok(enc, ptr, end, nextTokPtr) \
- XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
-
-#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
- XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
-
-#ifdef XML_DTD
-
-#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
- XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
-
-#endif /* XML_DTD */
-
-/* This is used for performing a 2nd-level tokenization on the content
- of a literal that has already been returned by XmlTok.
-*/
-#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
- (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
-
-#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
- XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
-
-#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
- XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
-
-#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
-
-#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
- (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
-
-#define XmlNameLength(enc, ptr) \
- (((enc)->nameLength)(enc, ptr))
-
-#define XmlSkipS(enc, ptr) \
- (((enc)->skipS)(enc, ptr))
-
-#define XmlGetAttributes(enc, ptr, attsMax, atts) \
- (((enc)->getAtts)(enc, ptr, attsMax, atts))
-
-#define XmlCharRefNumber(enc, ptr) \
- (((enc)->charRefNumber)(enc, ptr))
-
-#define XmlPredefinedEntityName(enc, ptr, end) \
- (((enc)->predefinedEntityName)(enc, ptr, end))
-
-#define XmlUpdatePosition(enc, ptr, end, pos) \
- (((enc)->updatePosition)(enc, ptr, end, pos))
-
-#define XmlIsPublicId(enc, ptr, end, badPtr) \
- (((enc)->isPublicId)(enc, ptr, end, badPtr))
-
-#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
- (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
-
-#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
- (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
-
-typedef struct {
- ENCODING initEnc;
- const ENCODING **encPtr;
-} INIT_ENCODING;
-
-int XmlParseXmlDecl(int isGeneralTextEntity,
- const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr,
- const char **versionPtr,
- const char **versionEndPtr,
- const char **encodingNamePtr,
- const ENCODING **namedEncodingPtr,
- int *standalonePtr);
-
-int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
-const ENCODING *XmlGetUtf8InternalEncoding(void);
-const ENCODING *XmlGetUtf16InternalEncoding(void);
-int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
-int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
-int XmlSizeOfUnknownEncoding(void);
-
-
-typedef int (XMLCALL *CONVERTER) (void *userData, const char *p);
-
-ENCODING *
-XmlInitUnknownEncoding(void *mem,
- int *table,
- CONVERTER convert,
- void *userData);
-
-int XmlParseXmlDeclNS(int isGeneralTextEntity,
- const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr,
- const char **versionPtr,
- const char **versionEndPtr,
- const char **encodingNamePtr,
- const ENCODING **namedEncodingPtr,
- int *standalonePtr);
-
-int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
-const ENCODING *XmlGetUtf8InternalEncodingNS(void);
-const ENCODING *XmlGetUtf16InternalEncodingNS(void);
-ENCODING *
-XmlInitUnknownEncodingNS(void *mem,
- int *table,
- CONVERTER convert,
- void *userData);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not XmlTok_INCLUDED */
diff --git a/components/expat/include/expat/xmltok_impl.h b/components/expat/include/expat/xmltok_impl.h
deleted file mode 100644
index da0ea60a65..0000000000
--- a/components/expat/include/expat/xmltok_impl.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
-*/
-
-enum {
- BT_NONXML,
- BT_MALFORM,
- BT_LT,
- BT_AMP,
- BT_RSQB,
- BT_LEAD2,
- BT_LEAD3,
- BT_LEAD4,
- BT_TRAIL,
- BT_CR,
- BT_LF,
- BT_GT,
- BT_QUOT,
- BT_APOS,
- BT_EQUALS,
- BT_QUEST,
- BT_EXCL,
- BT_SOL,
- BT_SEMI,
- BT_NUM,
- BT_LSQB,
- BT_S,
- BT_NMSTRT,
- BT_COLON,
- BT_HEX,
- BT_DIGIT,
- BT_NAME,
- BT_MINUS,
- BT_OTHER, /* known not to be a name or name start character */
- BT_NONASCII, /* might be a name or name start character */
- BT_PERCNT,
- BT_LPAR,
- BT_RPAR,
- BT_AST,
- BT_PLUS,
- BT_COMMA,
- BT_VERBAR
-};
-
-#include
diff --git a/components/expat/library/xmlparse.c b/components/expat/library/xmlparse.c
deleted file mode 100644
index e69622bcfb..0000000000
--- a/components/expat/library/xmlparse.c
+++ /dev/null
@@ -1,6475 +0,0 @@
-/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#include
-#include /* memset(), memcpy() */
-#include
-#include /* UINT_MAX */
-
-#ifdef WIN32
-#define getpid GetCurrentProcessId
-#else
-#include /* gettimeofday() */
-#include /* getpid() */
-#include /* getpid() */
-#endif
-
-#define XML_BUILDING_EXPAT 1
-
-#ifdef WIN32
-#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
-#elif defined(HAVE_EXPAT_CONFIG_H)
-#include
-#endif /* ndef WIN32 */
-
-#include "ascii.h"
-#include "expat.h"
-
-#ifdef XML_UNICODE
-#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
-#define XmlConvert XmlUtf16Convert
-#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
-#define XmlEncode XmlUtf16Encode
-/* Using pointer subtraction to convert to integer type. */
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
-typedef unsigned short ICHAR;
-#else
-#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
-#define XmlConvert XmlUtf8Convert
-#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
-#define XmlEncode XmlUtf8Encode
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
-typedef char ICHAR;
-#endif
-
-
-#ifndef XML_NS
-
-#define XmlInitEncodingNS XmlInitEncoding
-#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
-#undef XmlGetInternalEncodingNS
-#define XmlGetInternalEncodingNS XmlGetInternalEncoding
-#define XmlParseXmlDeclNS XmlParseXmlDecl
-
-#endif
-
-#ifdef XML_UNICODE
-
-#ifdef XML_UNICODE_WCHAR_T
-#define XML_T(x) (const wchar_t)x
-#define XML_L(x) L ## x
-#else
-#define XML_T(x) (const unsigned short)x
-#define XML_L(x) x
-#endif
-
-#else
-
-#define XML_T(x) x
-#define XML_L(x) x
-
-#endif
-
-/* Round up n to be a multiple of sz, where sz is a power of 2. */
-#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
-
-/* Handle the case where memmove() doesn't exist. */
-#ifndef HAVE_MEMMOVE
-#ifdef HAVE_BCOPY
-#define memmove(d,s,l) bcopy((s),(d),(l))
-#else
-//#error memmove does not exist on this platform, nor is a substitute available
-#endif /* HAVE_BCOPY */
-#endif /* HAVE_MEMMOVE */
-
-#include "internal.h"
-#include "xmltok.h"
-#include "xmlrole.h"
-
-typedef const XML_Char *KEY;
-
-typedef struct {
- KEY name;
-} NAMED;
-
-typedef struct {
- NAMED **v;
- unsigned char power;
- size_t size;
- size_t used;
- const XML_Memory_Handling_Suite *mem;
-} HASH_TABLE;
-
-/* Basic character hash algorithm, taken from Python's string hash:
- h = h * 1000003 ^ character, the constant being a prime number.
-
-*/
-#ifdef XML_UNICODE
-#define CHAR_HASH(h, c) \
- (((h) * 0xF4243) ^ (unsigned short)(c))
-#else
-#define CHAR_HASH(h, c) \
- (((h) * 0xF4243) ^ (unsigned char)(c))
-#endif
-
-/* For probing (after a collision) we need a step size relative prime
- to the hash table size, which is a power of 2. We use double-hashing,
- since we can calculate a second hash value cheaply by taking those bits
- of the first hash value that were discarded (masked out) when the table
- index was calculated: index = hash & mask, where mask = table->size - 1.
- We limit the maximum step size to table->size / 4 (mask >> 2) and make
- it odd, since odd numbers are always relative prime to a power of 2.
-*/
-#define SECOND_HASH(hash, mask, power) \
- ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
-#define PROBE_STEP(hash, mask, power) \
- ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
-
-typedef struct {
- NAMED **p;
- NAMED **end;
-} HASH_TABLE_ITER;
-
-#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
-#define INIT_DATA_BUF_SIZE 1024
-#define INIT_ATTS_SIZE 16
-#define INIT_ATTS_VERSION 0xFFFFFFFF
-#define INIT_BLOCK_SIZE 1024
-#define INIT_BUFFER_SIZE 1024
-
-#define EXPAND_SPARE 24
-
-typedef struct binding {
- struct prefix *prefix;
- struct binding *nextTagBinding;
- struct binding *prevPrefixBinding;
- const struct attribute_id *attId;
- XML_Char *uri;
- int uriLen;
- int uriAlloc;
-} BINDING;
-
-typedef struct prefix {
- const XML_Char *name;
- BINDING *binding;
-} PREFIX;
-
-typedef struct {
- const XML_Char *str;
- const XML_Char *localPart;
- const XML_Char *prefix;
- int strLen;
- int uriLen;
- int prefixLen;
-} TAG_NAME;
-
-/* TAG represents an open element.
- The name of the element is stored in both the document and API
- encodings. The memory buffer 'buf' is a separately-allocated
- memory area which stores the name. During the XML_Parse()/
- XMLParseBuffer() when the element is open, the memory for the 'raw'
- version of the name (in the document encoding) is shared with the
- document buffer. If the element is open across calls to
- XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
- contain the 'raw' name as well.
-
- A parser re-uses these structures, maintaining a list of allocated
- TAG objects in a free list.
-*/
-typedef struct tag {
- struct tag *parent; /* parent of this element */
- const char *rawName; /* tagName in the original encoding */
- int rawNameLength;
- TAG_NAME name; /* tagName in the API encoding */
- char *buf; /* buffer for name components */
- char *bufEnd; /* end of the buffer */
- BINDING *bindings;
-} TAG;
-
-typedef struct {
- const XML_Char *name;
- const XML_Char *textPtr;
- int textLen; /* length in XML_Chars */
- int processed; /* # of processed bytes - when suspended */
- const XML_Char *systemId;
- const XML_Char *base;
- const XML_Char *publicId;
- const XML_Char *notation;
- XML_Bool open;
- XML_Bool is_param;
- XML_Bool is_internal; /* true if declared in internal subset outside PE */
-} ENTITY;
-
-typedef struct {
- enum XML_Content_Type type;
- enum XML_Content_Quant quant;
- const XML_Char * name;
- int firstchild;
- int lastchild;
- int childcnt;
- int nextsib;
-} CONTENT_SCAFFOLD;
-
-#define INIT_SCAFFOLD_ELEMENTS 32
-
-typedef struct block {
- struct block *next;
- int size;
- XML_Char s[1];
-} BLOCK;
-
-typedef struct {
- BLOCK *blocks;
- BLOCK *freeBlocks;
- const XML_Char *end;
- XML_Char *ptr;
- XML_Char *start;
- const XML_Memory_Handling_Suite *mem;
-} STRING_POOL;
-
-/* The XML_Char before the name is used to determine whether
- an attribute has been specified. */
-typedef struct attribute_id {
- XML_Char *name;
- PREFIX *prefix;
- XML_Bool maybeTokenized;
- XML_Bool xmlns;
-} ATTRIBUTE_ID;
-
-typedef struct {
- const ATTRIBUTE_ID *id;
- XML_Bool isCdata;
- const XML_Char *value;
-} DEFAULT_ATTRIBUTE;
-
-typedef struct {
- unsigned long version;
- unsigned long hash;
- const XML_Char *uriName;
-} NS_ATT;
-
-typedef struct {
- const XML_Char *name;
- PREFIX *prefix;
- const ATTRIBUTE_ID *idAtt;
- int nDefaultAtts;
- int allocDefaultAtts;
- DEFAULT_ATTRIBUTE *defaultAtts;
-} ELEMENT_TYPE;
-
-typedef struct {
- HASH_TABLE generalEntities;
- HASH_TABLE elementTypes;
- HASH_TABLE attributeIds;
- HASH_TABLE prefixes;
- STRING_POOL pool;
- STRING_POOL entityValuePool;
- /* false once a parameter entity reference has been skipped */
- XML_Bool keepProcessing;
- /* true once an internal or external PE reference has been encountered;
- this includes the reference to an external subset */
- XML_Bool hasParamEntityRefs;
- XML_Bool standalone;
-#ifdef XML_DTD
- /* indicates if external PE has been read */
- XML_Bool paramEntityRead;
- HASH_TABLE paramEntities;
-#endif /* XML_DTD */
- PREFIX defaultPrefix;
- /* === scaffolding for building content model === */
- XML_Bool in_eldecl;
- CONTENT_SCAFFOLD *scaffold;
- unsigned contentStringLen;
- unsigned scaffSize;
- unsigned scaffCount;
- int scaffLevel;
- int *scaffIndex;
-} DTD;
-
-typedef struct open_internal_entity {
- const char *internalEventPtr;
- const char *internalEventEndPtr;
- struct open_internal_entity *next;
- ENTITY *entity;
- int startTagLevel;
- XML_Bool betweenDecl; /* WFC: PE Between Declarations */
-} OPEN_INTERNAL_ENTITY;
-
-typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr);
-
-static Processor prologProcessor;
-static Processor prologInitProcessor;
-static Processor contentProcessor;
-static Processor cdataSectionProcessor;
-#ifdef XML_DTD
-static Processor ignoreSectionProcessor;
-static Processor externalParEntProcessor;
-static Processor externalParEntInitProcessor;
-static Processor entityValueProcessor;
-static Processor entityValueInitProcessor;
-#endif /* XML_DTD */
-static Processor epilogProcessor;
-static Processor errorProcessor;
-static Processor externalEntityInitProcessor;
-static Processor externalEntityInitProcessor2;
-static Processor externalEntityInitProcessor3;
-static Processor externalEntityContentProcessor;
-static Processor internalEntityProcessor;
-
-static enum XML_Error
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
-static enum XML_Error
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
- const char *s, const char *next);
-static enum XML_Error
-initializeEncoding(XML_Parser parser);
-static enum XML_Error
-doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
- const char *end, int tok, const char *next, const char **nextPtr,
- XML_Bool haveMore);
-static enum XML_Error
-processInternalEntity(XML_Parser parser, ENTITY *entity,
- XML_Bool betweenDecl);
-static enum XML_Error
-doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
- const char *start, const char *end, const char **endPtr,
- XML_Bool haveMore);
-static enum XML_Error
-doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
- const char *end, const char **nextPtr, XML_Bool haveMore);
-#ifdef XML_DTD
-static enum XML_Error
-doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
- const char *end, const char **nextPtr, XML_Bool haveMore);
-#endif /* XML_DTD */
-
-static enum XML_Error
-storeAtts(XML_Parser parser, const ENCODING *, const char *s,
- TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
-static enum XML_Error
-addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
- const XML_Char *uri, BINDING **bindingsPtr);
-static int
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
- XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
-static enum XML_Error
-storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
- const char *, const char *, STRING_POOL *);
-static enum XML_Error
-appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
- const char *, const char *, STRING_POOL *);
-static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
-static int
-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
-static enum XML_Error
-storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
-static int
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end);
-static int
-reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
-static void
-reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
-
-static const XML_Char * getContext(XML_Parser parser);
-static XML_Bool
-setContext(XML_Parser parser, const XML_Char *context);
-
-static void FASTCALL normalizePublicId(XML_Char *s);
-
-static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
-/* do not call if parentParser != NULL */
-static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
-static void
-dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
-static int
-dtdCopy(XML_Parser oldParser,
- DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
-static int
-copyEntityTable(XML_Parser oldParser,
- HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
-static NAMED *
-lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
-static void FASTCALL
-hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
-static void FASTCALL hashTableClear(HASH_TABLE *);
-static void FASTCALL hashTableDestroy(HASH_TABLE *);
-static void FASTCALL
-hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
-static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
-
-static void FASTCALL
-poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
-static void FASTCALL poolClear(STRING_POOL *);
-static void FASTCALL poolDestroy(STRING_POOL *);
-static XML_Char *
-poolAppend(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end);
-static XML_Char *
-poolStoreString(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end);
-static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
-static const XML_Char * FASTCALL
-poolCopyString(STRING_POOL *pool, const XML_Char *s);
-static const XML_Char *
-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
-static const XML_Char * FASTCALL
-poolAppendString(STRING_POOL *pool, const XML_Char *s);
-
-static int FASTCALL nextScaffoldPart(XML_Parser parser);
-static XML_Content * build_model(XML_Parser parser);
-static ELEMENT_TYPE *
-getElementType(XML_Parser parser, const ENCODING *enc,
- const char *ptr, const char *end);
-
-static unsigned long generate_hash_secret_salt(XML_Parser parser);
-static XML_Bool startParsing(XML_Parser parser);
-
-static XML_Parser
-parserCreate(const XML_Char *encodingName,
- const XML_Memory_Handling_Suite *memsuite,
- const XML_Char *nameSep,
- DTD *dtd);
-
-static void
-parserInit(XML_Parser parser, const XML_Char *encodingName);
-
-#define poolStart(pool) ((pool)->start)
-#define poolEnd(pool) ((pool)->ptr)
-#define poolLength(pool) ((pool)->ptr - (pool)->start)
-#define poolChop(pool) ((void)--(pool->ptr))
-#define poolLastChar(pool) (((pool)->ptr)[-1])
-#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
-#define poolFinish(pool) ((pool)->start = (pool)->ptr)
-#define poolAppendChar(pool, c) \
- (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
- ? 0 \
- : ((*((pool)->ptr)++ = c), 1))
-
-struct XML_ParserStruct {
- /* The first member must be userData so that the XML_GetUserData
- macro works. */
- void *m_userData;
- void *m_handlerArg;
- char *m_buffer;
- const XML_Memory_Handling_Suite m_mem;
- /* first character to be parsed */
- const char *m_bufferPtr;
- /* past last character to be parsed */
- char *m_bufferEnd;
- /* allocated end of buffer */
- const char *m_bufferLim;
- XML_Index m_parseEndByteIndex;
- const char *m_parseEndPtr;
- XML_Char *m_dataBuf;
- XML_Char *m_dataBufEnd;
- XML_StartElementHandler m_startElementHandler;
- XML_EndElementHandler m_endElementHandler;
- XML_CharacterDataHandler m_characterDataHandler;
- XML_ProcessingInstructionHandler m_processingInstructionHandler;
- XML_CommentHandler m_commentHandler;
- XML_StartCdataSectionHandler m_startCdataSectionHandler;
- XML_EndCdataSectionHandler m_endCdataSectionHandler;
- XML_DefaultHandler m_defaultHandler;
- XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
- XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
- XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
- XML_NotationDeclHandler m_notationDeclHandler;
- XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
- XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
- XML_NotStandaloneHandler m_notStandaloneHandler;
- XML_ExternalEntityRefHandler m_externalEntityRefHandler;
- XML_Parser m_externalEntityRefHandlerArg;
- XML_SkippedEntityHandler m_skippedEntityHandler;
- XML_UnknownEncodingHandler m_unknownEncodingHandler;
- XML_ElementDeclHandler m_elementDeclHandler;
- XML_AttlistDeclHandler m_attlistDeclHandler;
- XML_EntityDeclHandler m_entityDeclHandler;
- XML_XmlDeclHandler m_xmlDeclHandler;
- const ENCODING *m_encoding;
- INIT_ENCODING m_initEncoding;
- const ENCODING *m_internalEncoding;
- const XML_Char *m_protocolEncodingName;
- XML_Bool m_ns;
- XML_Bool m_ns_triplets;
- void *m_unknownEncodingMem;
- void *m_unknownEncodingData;
- void *m_unknownEncodingHandlerData;
- void (XMLCALL *m_unknownEncodingRelease)(void *);
- PROLOG_STATE m_prologState;
- Processor *m_processor;
- enum XML_Error m_errorCode;
- const char *m_eventPtr;
- const char *m_eventEndPtr;
- const char *m_positionPtr;
- OPEN_INTERNAL_ENTITY *m_openInternalEntities;
- OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
- XML_Bool m_defaultExpandInternalEntities;
- int m_tagLevel;
- ENTITY *m_declEntity;
- const XML_Char *m_doctypeName;
- const XML_Char *m_doctypeSysid;
- const XML_Char *m_doctypePubid;
- const XML_Char *m_declAttributeType;
- const XML_Char *m_declNotationName;
- const XML_Char *m_declNotationPublicId;
- ELEMENT_TYPE *m_declElementType;
- ATTRIBUTE_ID *m_declAttributeId;
- XML_Bool m_declAttributeIsCdata;
- XML_Bool m_declAttributeIsId;
- DTD *m_dtd;
- const XML_Char *m_curBase;
- TAG *m_tagStack;
- TAG *m_freeTagList;
- BINDING *m_inheritedBindings;
- BINDING *m_freeBindingList;
- int m_attsSize;
- int m_nSpecifiedAtts;
- int m_idAttIndex;
- ATTRIBUTE *m_atts;
- NS_ATT *m_nsAtts;
- unsigned long m_nsAttsVersion;
- unsigned char m_nsAttsPower;
-#ifdef XML_ATTR_INFO
- XML_AttrInfo *m_attInfo;
-#endif
- POSITION m_position;
- STRING_POOL m_tempPool;
- STRING_POOL m_temp2Pool;
- char *m_groupConnector;
- unsigned int m_groupSize;
- XML_Char m_namespaceSeparator;
- XML_Parser m_parentParser;
- XML_ParsingStatus m_parsingStatus;
-#ifdef XML_DTD
- XML_Bool m_isParamEntity;
- XML_Bool m_useForeignDTD;
- enum XML_ParamEntityParsing m_paramEntityParsing;
-#endif
- unsigned long m_hash_secret_salt;
-};
-
-#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
-#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
-#define FREE(p) (parser->m_mem.free_fcn((p)))
-
-#define userData (parser->m_userData)
-#define handlerArg (parser->m_handlerArg)
-#define startElementHandler (parser->m_startElementHandler)
-#define endElementHandler (parser->m_endElementHandler)
-#define characterDataHandler (parser->m_characterDataHandler)
-#define processingInstructionHandler \
- (parser->m_processingInstructionHandler)
-#define commentHandler (parser->m_commentHandler)
-#define startCdataSectionHandler \
- (parser->m_startCdataSectionHandler)
-#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
-#define defaultHandler (parser->m_defaultHandler)
-#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
-#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
-#define unparsedEntityDeclHandler \
- (parser->m_unparsedEntityDeclHandler)
-#define notationDeclHandler (parser->m_notationDeclHandler)
-#define startNamespaceDeclHandler \
- (parser->m_startNamespaceDeclHandler)
-#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
-#define notStandaloneHandler (parser->m_notStandaloneHandler)
-#define externalEntityRefHandler \
- (parser->m_externalEntityRefHandler)
-#define externalEntityRefHandlerArg \
- (parser->m_externalEntityRefHandlerArg)
-#define internalEntityRefHandler \
- (parser->m_internalEntityRefHandler)
-#define skippedEntityHandler (parser->m_skippedEntityHandler)
-#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
-#define elementDeclHandler (parser->m_elementDeclHandler)
-#define attlistDeclHandler (parser->m_attlistDeclHandler)
-#define entityDeclHandler (parser->m_entityDeclHandler)
-#define xmlDeclHandler (parser->m_xmlDeclHandler)
-#define encoding (parser->m_encoding)
-#define initEncoding (parser->m_initEncoding)
-#define internalEncoding (parser->m_internalEncoding)
-#define unknownEncodingMem (parser->m_unknownEncodingMem)
-#define unknownEncodingData (parser->m_unknownEncodingData)
-#define unknownEncodingHandlerData \
- (parser->m_unknownEncodingHandlerData)
-#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
-#define protocolEncodingName (parser->m_protocolEncodingName)
-#define ns (parser->m_ns)
-#define ns_triplets (parser->m_ns_triplets)
-#define prologState (parser->m_prologState)
-#define processor (parser->m_processor)
-#define errorCode (parser->m_errorCode)
-#define eventPtr (parser->m_eventPtr)
-#define eventEndPtr (parser->m_eventEndPtr)
-#define positionPtr (parser->m_positionPtr)
-#define position (parser->m_position)
-#define openInternalEntities (parser->m_openInternalEntities)
-#define freeInternalEntities (parser->m_freeInternalEntities)
-#define defaultExpandInternalEntities \
- (parser->m_defaultExpandInternalEntities)
-#define tagLevel (parser->m_tagLevel)
-#define buffer (parser->m_buffer)
-#define bufferPtr (parser->m_bufferPtr)
-#define bufferEnd (parser->m_bufferEnd)
-#define parseEndByteIndex (parser->m_parseEndByteIndex)
-#define parseEndPtr (parser->m_parseEndPtr)
-#define bufferLim (parser->m_bufferLim)
-#define dataBuf (parser->m_dataBuf)
-#define dataBufEnd (parser->m_dataBufEnd)
-#define _dtd (parser->m_dtd)
-#define curBase (parser->m_curBase)
-#define declEntity (parser->m_declEntity)
-#define doctypeName (parser->m_doctypeName)
-#define doctypeSysid (parser->m_doctypeSysid)
-#define doctypePubid (parser->m_doctypePubid)
-#define declAttributeType (parser->m_declAttributeType)
-#define declNotationName (parser->m_declNotationName)
-#define declNotationPublicId (parser->m_declNotationPublicId)
-#define declElementType (parser->m_declElementType)
-#define declAttributeId (parser->m_declAttributeId)
-#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
-#define declAttributeIsId (parser->m_declAttributeIsId)
-#define freeTagList (parser->m_freeTagList)
-#define freeBindingList (parser->m_freeBindingList)
-#define inheritedBindings (parser->m_inheritedBindings)
-#define tagStack (parser->m_tagStack)
-#define atts (parser->m_atts)
-#define attsSize (parser->m_attsSize)
-#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
-#define idAttIndex (parser->m_idAttIndex)
-#define nsAtts (parser->m_nsAtts)
-#define nsAttsVersion (parser->m_nsAttsVersion)
-#define nsAttsPower (parser->m_nsAttsPower)
-#define attInfo (parser->m_attInfo)
-#define tempPool (parser->m_tempPool)
-#define temp2Pool (parser->m_temp2Pool)
-#define groupConnector (parser->m_groupConnector)
-#define groupSize (parser->m_groupSize)
-#define namespaceSeparator (parser->m_namespaceSeparator)
-#define parentParser (parser->m_parentParser)
-#define ps_parsing (parser->m_parsingStatus.parsing)
-#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
-#ifdef XML_DTD
-#define isParamEntity (parser->m_isParamEntity)
-#define useForeignDTD (parser->m_useForeignDTD)
-#define paramEntityParsing (parser->m_paramEntityParsing)
-#endif /* XML_DTD */
-#define hash_secret_salt (parser->m_hash_secret_salt)
-
-XML_Parser XMLCALL
-XML_ParserCreate(const XML_Char *encodingName)
-{
- return XML_ParserCreate_MM(encodingName, NULL, NULL);
-}
-
-XML_Parser XMLCALL
-XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
-{
- XML_Char tmp[2];
- *tmp = nsSep;
- return XML_ParserCreate_MM(encodingName, NULL, tmp);
-}
-
-static const XML_Char implicitContext[] = {
- ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
- ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
- ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
- ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
- ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
- ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
-};
-
-static unsigned long
-gather_time_entropy(void)
-{
-#ifdef WIN32
- FILETIME ft;
- GetSystemTimeAsFileTime(&ft); /* never fails */
- return ft.dwHighDateTime ^ ft.dwLowDateTime;
-#else
- struct timeval tv;
- int gettimeofday_res;
-
- gettimeofday_res = gettimeofday(&tv, NULL);
- assert (gettimeofday_res == 0);
-
- /* Microseconds time is <20 bits entropy */
- return tv.tv_usec;
-#endif
-}
-
-static unsigned long
-generate_hash_secret_salt(XML_Parser parser)
-{
-#ifdef __CloudABI__
- unsigned long entropy;
- (void)parser;
- (void)gather_time_entropy;
- arc4random_buf(&entropy, sizeof(entropy));
- return entropy;
-#else
- /* Process ID is 0 bits entropy if attacker has local access
- * XML_Parser address is few bits of entropy if attacker has local access */
-// const unsigned long entropy =
-// gather_time_entropy() ^ getpid() ^ (unsigned long)parser;
- const unsigned long entropy = (unsigned long)parser;
-
- /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
- if (sizeof(unsigned long) == 4) {
- return entropy * 2147483647;
- } else {
- return entropy * (unsigned long)2305843009213693951;
- }
-#endif
-}
-
-static XML_Bool /* only valid for root parser */
-startParsing(XML_Parser parser)
-{
- /* hash functions must be initialized before setContext() is called */
- if (hash_secret_salt == 0)
- hash_secret_salt = generate_hash_secret_salt(parser);
- if (ns) {
- /* implicit context only set for root parser, since child
- parsers (i.e. external entity parsers) will inherit it
- */
- return setContext(parser, implicitContext);
- }
- return XML_TRUE;
-}
-
-XML_Parser XMLCALL
-XML_ParserCreate_MM(const XML_Char *encodingName,
- const XML_Memory_Handling_Suite *memsuite,
- const XML_Char *nameSep)
-{
- return parserCreate(encodingName, memsuite, nameSep, NULL);
-}
-
-static XML_Parser
-parserCreate(const XML_Char *encodingName,
- const XML_Memory_Handling_Suite *memsuite,
- const XML_Char *nameSep,
- DTD *dtd)
-{
- XML_Parser parser;
-
- if (memsuite) {
- XML_Memory_Handling_Suite *mtemp;
- parser = (XML_Parser)
- memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
- if (parser != NULL) {
- mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
- mtemp->malloc_fcn = memsuite->malloc_fcn;
- mtemp->realloc_fcn = memsuite->realloc_fcn;
- mtemp->free_fcn = memsuite->free_fcn;
- }
- }
- else {
- XML_Memory_Handling_Suite *mtemp;
- parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
- if (parser != NULL) {
- mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
- mtemp->malloc_fcn = malloc;
- mtemp->realloc_fcn = realloc;
- mtemp->free_fcn = free;
- }
- }
-
- if (!parser)
- return parser;
-
- buffer = NULL;
- bufferLim = NULL;
-
- attsSize = INIT_ATTS_SIZE;
- atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
- if (atts == NULL) {
- FREE(parser);
- return NULL;
- }
-#ifdef XML_ATTR_INFO
- attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));
- if (attInfo == NULL) {
- FREE(atts);
- FREE(parser);
- return NULL;
- }
-#endif
- dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
- if (dataBuf == NULL) {
- FREE(atts);
-#ifdef XML_ATTR_INFO
- FREE(attInfo);
-#endif
- FREE(parser);
- return NULL;
- }
- dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
-
- if (dtd)
- _dtd = dtd;
- else {
- _dtd = dtdCreate(&parser->m_mem);
- if (_dtd == NULL) {
- FREE(dataBuf);
- FREE(atts);
-#ifdef XML_ATTR_INFO
- FREE(attInfo);
-#endif
- FREE(parser);
- return NULL;
- }
- }
-
- freeBindingList = NULL;
- freeTagList = NULL;
- freeInternalEntities = NULL;
-
- groupSize = 0;
- groupConnector = NULL;
-
- unknownEncodingHandler = NULL;
- unknownEncodingHandlerData = NULL;
-
- namespaceSeparator = ASCII_EXCL;
- ns = XML_FALSE;
- ns_triplets = XML_FALSE;
-
- nsAtts = NULL;
- nsAttsVersion = 0;
- nsAttsPower = 0;
-
- poolInit(&tempPool, &(parser->m_mem));
- poolInit(&temp2Pool, &(parser->m_mem));
- parserInit(parser, encodingName);
-
- if (encodingName && !protocolEncodingName) {
- XML_ParserFree(parser);
- return NULL;
- }
-
- if (nameSep) {
- ns = XML_TRUE;
- internalEncoding = XmlGetInternalEncodingNS();
- namespaceSeparator = *nameSep;
- }
- else {
- internalEncoding = XmlGetInternalEncoding();
- }
-
- return parser;
-}
-
-static void
-parserInit(XML_Parser parser, const XML_Char *encodingName)
-{
- processor = prologInitProcessor;
- XmlPrologStateInit(&prologState);
- protocolEncodingName = (encodingName != NULL
- ? poolCopyString(&tempPool, encodingName)
- : NULL);
- curBase = NULL;
- XmlInitEncoding(&initEncoding, &encoding, 0);
- userData = NULL;
- handlerArg = NULL;
- startElementHandler = NULL;
- endElementHandler = NULL;
- characterDataHandler = NULL;
- processingInstructionHandler = NULL;
- commentHandler = NULL;
- startCdataSectionHandler = NULL;
- endCdataSectionHandler = NULL;
- defaultHandler = NULL;
- startDoctypeDeclHandler = NULL;
- endDoctypeDeclHandler = NULL;
- unparsedEntityDeclHandler = NULL;
- notationDeclHandler = NULL;
- startNamespaceDeclHandler = NULL;
- endNamespaceDeclHandler = NULL;
- notStandaloneHandler = NULL;
- externalEntityRefHandler = NULL;
- externalEntityRefHandlerArg = parser;
- skippedEntityHandler = NULL;
- elementDeclHandler = NULL;
- attlistDeclHandler = NULL;
- entityDeclHandler = NULL;
- xmlDeclHandler = NULL;
- bufferPtr = buffer;
- bufferEnd = buffer;
- parseEndByteIndex = 0;
- parseEndPtr = NULL;
- declElementType = NULL;
- declAttributeId = NULL;
- declEntity = NULL;
- doctypeName = NULL;
- doctypeSysid = NULL;
- doctypePubid = NULL;
- declAttributeType = NULL;
- declNotationName = NULL;
- declNotationPublicId = NULL;
- declAttributeIsCdata = XML_FALSE;
- declAttributeIsId = XML_FALSE;
- memset(&position, 0, sizeof(POSITION));
- errorCode = XML_ERROR_NONE;
- eventPtr = NULL;
- eventEndPtr = NULL;
- positionPtr = NULL;
- openInternalEntities = NULL;
- defaultExpandInternalEntities = XML_TRUE;
- tagLevel = 0;
- tagStack = NULL;
- inheritedBindings = NULL;
- nSpecifiedAtts = 0;
- unknownEncodingMem = NULL;
- unknownEncodingRelease = NULL;
- unknownEncodingData = NULL;
- parentParser = NULL;
- ps_parsing = XML_INITIALIZED;
-#ifdef XML_DTD
- isParamEntity = XML_FALSE;
- useForeignDTD = XML_FALSE;
- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
-#endif
- hash_secret_salt = 0;
-}
-
-/* moves list of bindings to freeBindingList */
-static void FASTCALL
-moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
-{
- while (bindings) {
- BINDING *b = bindings;
- bindings = bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- }
-}
-
-XML_Bool XMLCALL
-XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
-{
- TAG *tStk;
- OPEN_INTERNAL_ENTITY *openEntityList;
- if (parentParser)
- return XML_FALSE;
- /* move tagStack to freeTagList */
- tStk = tagStack;
- while (tStk) {
- TAG *tag = tStk;
- tStk = tStk->parent;
- tag->parent = freeTagList;
- moveToFreeBindingList(parser, tag->bindings);
- tag->bindings = NULL;
- freeTagList = tag;
- }
- /* move openInternalEntities to freeInternalEntities */
- openEntityList = openInternalEntities;
- while (openEntityList) {
- OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
- openEntityList = openEntity->next;
- openEntity->next = freeInternalEntities;
- freeInternalEntities = openEntity;
- }
- moveToFreeBindingList(parser, inheritedBindings);
- FREE(unknownEncodingMem);
- if (unknownEncodingRelease)
- unknownEncodingRelease(unknownEncodingData);
- poolClear(&tempPool);
- poolClear(&temp2Pool);
- parserInit(parser, encodingName);
- dtdReset(_dtd, &parser->m_mem);
- return XML_TRUE;
-}
-
-enum XML_Status XMLCALL
-XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
-{
- /* Block after XML_Parse()/XML_ParseBuffer() has been called.
- XXX There's no way for the caller to determine which of the
- XXX possible error cases caused the XML_STATUS_ERROR return.
- */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
- return XML_STATUS_ERROR;
- if (encodingName == NULL)
- protocolEncodingName = NULL;
- else {
- protocolEncodingName = poolCopyString(&tempPool, encodingName);
- if (!protocolEncodingName)
- return XML_STATUS_ERROR;
- }
- return XML_STATUS_OK;
-}
-
-XML_Parser XMLCALL
-XML_ExternalEntityParserCreate(XML_Parser oldParser,
- const XML_Char *context,
- const XML_Char *encodingName)
-{
- XML_Parser parser = oldParser;
- DTD *newDtd = NULL;
- DTD *oldDtd = _dtd;
- XML_StartElementHandler oldStartElementHandler = startElementHandler;
- XML_EndElementHandler oldEndElementHandler = endElementHandler;
- XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
- XML_ProcessingInstructionHandler oldProcessingInstructionHandler
- = processingInstructionHandler;
- XML_CommentHandler oldCommentHandler = commentHandler;
- XML_StartCdataSectionHandler oldStartCdataSectionHandler
- = startCdataSectionHandler;
- XML_EndCdataSectionHandler oldEndCdataSectionHandler
- = endCdataSectionHandler;
- XML_DefaultHandler oldDefaultHandler = defaultHandler;
- XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
- = unparsedEntityDeclHandler;
- XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
- XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
- = startNamespaceDeclHandler;
- XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
- = endNamespaceDeclHandler;
- XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
- XML_ExternalEntityRefHandler oldExternalEntityRefHandler
- = externalEntityRefHandler;
- XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
- XML_UnknownEncodingHandler oldUnknownEncodingHandler
- = unknownEncodingHandler;
- XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
- XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
- XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
- XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
- ELEMENT_TYPE * oldDeclElementType = declElementType;
-
- void *oldUserData = userData;
- void *oldHandlerArg = handlerArg;
- XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
- XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
-#ifdef XML_DTD
- enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
- int oldInEntityValue = prologState.inEntityValue;
-#endif
- XML_Bool oldns_triplets = ns_triplets;
- /* Note that the new parser shares the same hash secret as the old
- parser, so that dtdCopy and copyEntityTable can lookup values
- from hash tables associated with either parser without us having
- to worry which hash secrets each table has.
- */
- unsigned long oldhash_secret_salt = hash_secret_salt;
-
-#ifdef XML_DTD
- if (!context)
- newDtd = oldDtd;
-#endif /* XML_DTD */
-
- /* Note that the magical uses of the pre-processor to make field
- access look more like C++ require that `parser' be overwritten
- here. This makes this function more painful to follow than it
- would be otherwise.
- */
- if (ns) {
- XML_Char tmp[2];
- *tmp = namespaceSeparator;
- parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
- }
- else {
- parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
- }
-
- if (!parser)
- return NULL;
-
- startElementHandler = oldStartElementHandler;
- endElementHandler = oldEndElementHandler;
- characterDataHandler = oldCharacterDataHandler;
- processingInstructionHandler = oldProcessingInstructionHandler;
- commentHandler = oldCommentHandler;
- startCdataSectionHandler = oldStartCdataSectionHandler;
- endCdataSectionHandler = oldEndCdataSectionHandler;
- defaultHandler = oldDefaultHandler;
- unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
- notationDeclHandler = oldNotationDeclHandler;
- startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
- endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
- notStandaloneHandler = oldNotStandaloneHandler;
- externalEntityRefHandler = oldExternalEntityRefHandler;
- skippedEntityHandler = oldSkippedEntityHandler;
- unknownEncodingHandler = oldUnknownEncodingHandler;
- elementDeclHandler = oldElementDeclHandler;
- attlistDeclHandler = oldAttlistDeclHandler;
- entityDeclHandler = oldEntityDeclHandler;
- xmlDeclHandler = oldXmlDeclHandler;
- declElementType = oldDeclElementType;
- userData = oldUserData;
- if (oldUserData == oldHandlerArg)
- handlerArg = userData;
- else
- handlerArg = parser;
- if (oldExternalEntityRefHandlerArg != oldParser)
- externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
- defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
- ns_triplets = oldns_triplets;
- hash_secret_salt = oldhash_secret_salt;
- parentParser = oldParser;
-#ifdef XML_DTD
- paramEntityParsing = oldParamEntityParsing;
- prologState.inEntityValue = oldInEntityValue;
- if (context) {
-#endif /* XML_DTD */
- if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
- || !setContext(parser, context)) {
- XML_ParserFree(parser);
- return NULL;
- }
- processor = externalEntityInitProcessor;
-#ifdef XML_DTD
- }
- else {
- /* The DTD instance referenced by _dtd is shared between the document's
- root parser and external PE parsers, therefore one does not need to
- call setContext. In addition, one also *must* not call setContext,
- because this would overwrite existing prefix->binding pointers in
- _dtd with ones that get destroyed with the external PE parser.
- This would leave those prefixes with dangling pointers.
- */
- isParamEntity = XML_TRUE;
- XmlPrologStateInitExternalEntity(&prologState);
- processor = externalParEntInitProcessor;
- }
-#endif /* XML_DTD */
- return parser;
-}
-
-static void FASTCALL
-destroyBindings(BINDING *bindings, XML_Parser parser)
-{
- for (;;) {
- BINDING *b = bindings;
- if (!b)
- break;
- bindings = b->nextTagBinding;
- FREE(b->uri);
- FREE(b);
- }
-}
-
-void XMLCALL
-XML_ParserFree(XML_Parser parser)
-{
- TAG *tagList;
- OPEN_INTERNAL_ENTITY *entityList;
- if (parser == NULL)
- return;
- /* free tagStack and freeTagList */
- tagList = tagStack;
- for (;;) {
- TAG *p;
- if (tagList == NULL) {
- if (freeTagList == NULL)
- break;
- tagList = freeTagList;
- freeTagList = NULL;
- }
- p = tagList;
- tagList = tagList->parent;
- FREE(p->buf);
- destroyBindings(p->bindings, parser);
- FREE(p);
- }
- /* free openInternalEntities and freeInternalEntities */
- entityList = openInternalEntities;
- for (;;) {
- OPEN_INTERNAL_ENTITY *openEntity;
- if (entityList == NULL) {
- if (freeInternalEntities == NULL)
- break;
- entityList = freeInternalEntities;
- freeInternalEntities = NULL;
- }
- openEntity = entityList;
- entityList = entityList->next;
- FREE(openEntity);
- }
-
- destroyBindings(freeBindingList, parser);
- destroyBindings(inheritedBindings, parser);
- poolDestroy(&tempPool);
- poolDestroy(&temp2Pool);
-#ifdef XML_DTD
- /* external parameter entity parsers share the DTD structure
- parser->m_dtd with the root parser, so we must not destroy it
- */
- if (!isParamEntity && _dtd)
-#else
- if (_dtd)
-#endif /* XML_DTD */
- dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
- FREE((void *)atts);
-#ifdef XML_ATTR_INFO
- FREE((void *)attInfo);
-#endif
- FREE(groupConnector);
- FREE(buffer);
- FREE(dataBuf);
- FREE(nsAtts);
- FREE(unknownEncodingMem);
- if (unknownEncodingRelease)
- unknownEncodingRelease(unknownEncodingData);
- FREE(parser);
-}
-
-void XMLCALL
-XML_UseParserAsHandlerArg(XML_Parser parser)
-{
- handlerArg = parser;
-}
-
-enum XML_Error XMLCALL
-XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
-{
-#ifdef XML_DTD
- /* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
- return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
- useForeignDTD = useDTD;
- return XML_ERROR_NONE;
-#else
- return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
-#endif
-}
-
-void XMLCALL
-XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
-{
- /* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
- return;
- ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
-}
-
-void XMLCALL
-XML_SetUserData(XML_Parser parser, void *p)
-{
- if (handlerArg == userData)
- handlerArg = userData = p;
- else
- userData = p;
-}
-
-enum XML_Status XMLCALL
-XML_SetBase(XML_Parser parser, const XML_Char *p)
-{
- if (p) {
- p = poolCopyString(&_dtd->pool, p);
- if (!p)
- return XML_STATUS_ERROR;
- curBase = p;
- }
- else
- curBase = NULL;
- return XML_STATUS_OK;
-}
-
-const XML_Char * XMLCALL
-XML_GetBase(XML_Parser parser)
-{
- return curBase;
-}
-
-int XMLCALL
-XML_GetSpecifiedAttributeCount(XML_Parser parser)
-{
- return nSpecifiedAtts;
-}
-
-int XMLCALL
-XML_GetIdAttributeIndex(XML_Parser parser)
-{
- return idAttIndex;
-}
-
-#ifdef XML_ATTR_INFO
-const XML_AttrInfo * XMLCALL
-XML_GetAttributeInfo(XML_Parser parser)
-{
- return attInfo;
-}
-#endif
-
-void XMLCALL
-XML_SetElementHandler(XML_Parser parser,
- XML_StartElementHandler start,
- XML_EndElementHandler end)
-{
- startElementHandler = start;
- endElementHandler = end;
-}
-
-void XMLCALL
-XML_SetStartElementHandler(XML_Parser parser,
- XML_StartElementHandler start) {
- startElementHandler = start;
-}
-
-void XMLCALL
-XML_SetEndElementHandler(XML_Parser parser,
- XML_EndElementHandler end) {
- endElementHandler = end;
-}
-
-void XMLCALL
-XML_SetCharacterDataHandler(XML_Parser parser,
- XML_CharacterDataHandler handler)
-{
- characterDataHandler = handler;
-}
-
-void XMLCALL
-XML_SetProcessingInstructionHandler(XML_Parser parser,
- XML_ProcessingInstructionHandler handler)
-{
- processingInstructionHandler = handler;
-}
-
-void XMLCALL
-XML_SetCommentHandler(XML_Parser parser,
- XML_CommentHandler handler)
-{
- commentHandler = handler;
-}
-
-void XMLCALL
-XML_SetCdataSectionHandler(XML_Parser parser,
- XML_StartCdataSectionHandler start,
- XML_EndCdataSectionHandler end)
-{
- startCdataSectionHandler = start;
- endCdataSectionHandler = end;
-}
-
-void XMLCALL
-XML_SetStartCdataSectionHandler(XML_Parser parser,
- XML_StartCdataSectionHandler start) {
- startCdataSectionHandler = start;
-}
-
-void XMLCALL
-XML_SetEndCdataSectionHandler(XML_Parser parser,
- XML_EndCdataSectionHandler end) {
- endCdataSectionHandler = end;
-}
-
-void XMLCALL
-XML_SetDefaultHandler(XML_Parser parser,
- XML_DefaultHandler handler)
-{
- defaultHandler = handler;
- defaultExpandInternalEntities = XML_FALSE;
-}
-
-void XMLCALL
-XML_SetDefaultHandlerExpand(XML_Parser parser,
- XML_DefaultHandler handler)
-{
- defaultHandler = handler;
- defaultExpandInternalEntities = XML_TRUE;
-}
-
-void XMLCALL
-XML_SetDoctypeDeclHandler(XML_Parser parser,
- XML_StartDoctypeDeclHandler start,
- XML_EndDoctypeDeclHandler end)
-{
- startDoctypeDeclHandler = start;
- endDoctypeDeclHandler = end;
-}
-
-void XMLCALL
-XML_SetStartDoctypeDeclHandler(XML_Parser parser,
- XML_StartDoctypeDeclHandler start) {
- startDoctypeDeclHandler = start;
-}
-
-void XMLCALL
-XML_SetEndDoctypeDeclHandler(XML_Parser parser,
- XML_EndDoctypeDeclHandler end) {
- endDoctypeDeclHandler = end;
-}
-
-void XMLCALL
-XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
- XML_UnparsedEntityDeclHandler handler)
-{
- unparsedEntityDeclHandler = handler;
-}
-
-void XMLCALL
-XML_SetNotationDeclHandler(XML_Parser parser,
- XML_NotationDeclHandler handler)
-{
- notationDeclHandler = handler;
-}
-
-void XMLCALL
-XML_SetNamespaceDeclHandler(XML_Parser parser,
- XML_StartNamespaceDeclHandler start,
- XML_EndNamespaceDeclHandler end)
-{
- startNamespaceDeclHandler = start;
- endNamespaceDeclHandler = end;
-}
-
-void XMLCALL
-XML_SetStartNamespaceDeclHandler(XML_Parser parser,
- XML_StartNamespaceDeclHandler start) {
- startNamespaceDeclHandler = start;
-}
-
-void XMLCALL
-XML_SetEndNamespaceDeclHandler(XML_Parser parser,
- XML_EndNamespaceDeclHandler end) {
- endNamespaceDeclHandler = end;
-}
-
-void XMLCALL
-XML_SetNotStandaloneHandler(XML_Parser parser,
- XML_NotStandaloneHandler handler)
-{
- notStandaloneHandler = handler;
-}
-
-void XMLCALL
-XML_SetExternalEntityRefHandler(XML_Parser parser,
- XML_ExternalEntityRefHandler handler)
-{
- externalEntityRefHandler = handler;
-}
-
-void XMLCALL
-XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
-{
- if (arg)
- externalEntityRefHandlerArg = (XML_Parser)arg;
- else
- externalEntityRefHandlerArg = parser;
-}
-
-void XMLCALL
-XML_SetSkippedEntityHandler(XML_Parser parser,
- XML_SkippedEntityHandler handler)
-{
- skippedEntityHandler = handler;
-}
-
-void XMLCALL
-XML_SetUnknownEncodingHandler(XML_Parser parser,
- XML_UnknownEncodingHandler handler,
- void *data)
-{
- unknownEncodingHandler = handler;
- unknownEncodingHandlerData = data;
-}
-
-void XMLCALL
-XML_SetElementDeclHandler(XML_Parser parser,
- XML_ElementDeclHandler eldecl)
-{
- elementDeclHandler = eldecl;
-}
-
-void XMLCALL
-XML_SetAttlistDeclHandler(XML_Parser parser,
- XML_AttlistDeclHandler attdecl)
-{
- attlistDeclHandler = attdecl;
-}
-
-void XMLCALL
-XML_SetEntityDeclHandler(XML_Parser parser,
- XML_EntityDeclHandler handler)
-{
- entityDeclHandler = handler;
-}
-
-void XMLCALL
-XML_SetXmlDeclHandler(XML_Parser parser,
- XML_XmlDeclHandler handler) {
- xmlDeclHandler = handler;
-}
-
-int XMLCALL
-XML_SetParamEntityParsing(XML_Parser parser,
- enum XML_ParamEntityParsing peParsing)
-{
- /* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
- return 0;
-#ifdef XML_DTD
- paramEntityParsing = peParsing;
- return 1;
-#else
- return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
-#endif
-}
-
-int XMLCALL
-XML_SetHashSalt(XML_Parser parser,
- unsigned long hash_salt)
-{
- /* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
- return 0;
- hash_secret_salt = hash_salt;
- return 1;
-}
-
-enum XML_Status XMLCALL
-XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
-{
- switch (ps_parsing) {
- case XML_SUSPENDED:
- errorCode = XML_ERROR_SUSPENDED;
- return XML_STATUS_ERROR;
- case XML_FINISHED:
- errorCode = XML_ERROR_FINISHED;
- return XML_STATUS_ERROR;
- case XML_INITIALIZED:
- if (parentParser == NULL && !startParsing(parser)) {
- errorCode = XML_ERROR_NO_MEMORY;
- return XML_STATUS_ERROR;
- }
- default:
- ps_parsing = XML_PARSING;
- }
-
- if (len == 0) {
- ps_finalBuffer = (XML_Bool)isFinal;
- if (!isFinal)
- return XML_STATUS_OK;
- positionPtr = bufferPtr;
- parseEndPtr = bufferEnd;
-
- /* If data are left over from last buffer, and we now know that these
- data are the final chunk of input, then we have to check them again
- to detect errors based on that fact.
- */
- errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
-
- if (errorCode == XML_ERROR_NONE) {
- switch (ps_parsing) {
- case XML_SUSPENDED:
- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
- positionPtr = bufferPtr;
- return XML_STATUS_SUSPENDED;
- case XML_INITIALIZED:
- case XML_PARSING:
- ps_parsing = XML_FINISHED;
- /* fall through */
- default:
- return XML_STATUS_OK;
- }
- }
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
-#ifndef XML_CONTEXT_BYTES
- else if (bufferPtr == bufferEnd) {
- const char *end;
- int nLeftOver;
- enum XML_Status result;
- parseEndByteIndex += len;
- positionPtr = s;
- ps_finalBuffer = (XML_Bool)isFinal;
-
- errorCode = processor(parser, s, parseEndPtr = s + len, &end);
-
- if (errorCode != XML_ERROR_NONE) {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
- else {
- switch (ps_parsing) {
- case XML_SUSPENDED:
- result = XML_STATUS_SUSPENDED;
- break;
- case XML_INITIALIZED:
- case XML_PARSING:
- if (isFinal) {
- ps_parsing = XML_FINISHED;
- return XML_STATUS_OK;
- }
- /* fall through */
- default:
- result = XML_STATUS_OK;
- }
- }
-
- XmlUpdatePosition(encoding, positionPtr, end, &position);
- nLeftOver = s + len - end;
- if (nLeftOver) {
- if (buffer == NULL || nLeftOver > bufferLim - buffer) {
- /* FIXME avoid integer overflow */
- char *temp;
- temp = (buffer == NULL
- ? (char *)MALLOC(len * 2)
- : (char *)REALLOC(buffer, len * 2));
- if (temp == NULL) {
- errorCode = XML_ERROR_NO_MEMORY;
- eventPtr = eventEndPtr = NULL;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
- buffer = temp;
- bufferLim = buffer + len * 2;
- }
- memcpy(buffer, end, nLeftOver);
- }
- bufferPtr = buffer;
- bufferEnd = buffer + nLeftOver;
- positionPtr = bufferPtr;
- parseEndPtr = bufferEnd;
- eventPtr = bufferPtr;
- eventEndPtr = bufferPtr;
- return result;
- }
-#endif /* not defined XML_CONTEXT_BYTES */
- else {
- void *buff = XML_GetBuffer(parser, len);
- if (buff == NULL)
- return XML_STATUS_ERROR;
- else {
- memcpy(buff, s, len);
- return XML_ParseBuffer(parser, len, isFinal);
- }
- }
-}
-
-enum XML_Status XMLCALL
-XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
-{
- const char *start;
- enum XML_Status result = XML_STATUS_OK;
-
- switch (ps_parsing) {
- case XML_SUSPENDED:
- errorCode = XML_ERROR_SUSPENDED;
- return XML_STATUS_ERROR;
- case XML_FINISHED:
- errorCode = XML_ERROR_FINISHED;
- return XML_STATUS_ERROR;
- case XML_INITIALIZED:
- if (parentParser == NULL && !startParsing(parser)) {
- errorCode = XML_ERROR_NO_MEMORY;
- return XML_STATUS_ERROR;
- }
- default:
- ps_parsing = XML_PARSING;
- }
-
- start = bufferPtr;
- positionPtr = start;
- bufferEnd += len;
- parseEndPtr = bufferEnd;
- parseEndByteIndex += len;
- ps_finalBuffer = (XML_Bool)isFinal;
-
- errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
-
- if (errorCode != XML_ERROR_NONE) {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
- else {
- switch (ps_parsing) {
- case XML_SUSPENDED:
- result = XML_STATUS_SUSPENDED;
- break;
- case XML_INITIALIZED:
- case XML_PARSING:
- if (isFinal) {
- ps_parsing = XML_FINISHED;
- return result;
- }
- default: ; /* should not happen */
- }
- }
-
- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
- positionPtr = bufferPtr;
- return result;
-}
-
-void * XMLCALL
-XML_GetBuffer(XML_Parser parser, int len)
-{
- if (len < 0) {
- errorCode = XML_ERROR_NO_MEMORY;
- return NULL;
- }
- switch (ps_parsing) {
- case XML_SUSPENDED:
- errorCode = XML_ERROR_SUSPENDED;
- return NULL;
- case XML_FINISHED:
- errorCode = XML_ERROR_FINISHED;
- return NULL;
- default: ;
- }
-
- if (len > bufferLim - bufferEnd) {
-#ifdef XML_CONTEXT_BYTES
- int keep;
-#endif /* defined XML_CONTEXT_BYTES */
- /* Do not invoke signed arithmetic overflow: */
- int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr));
- if (neededSize < 0) {
- errorCode = XML_ERROR_NO_MEMORY;
- return NULL;
- }
-#ifdef XML_CONTEXT_BYTES
- keep = (int)(bufferPtr - buffer);
- if (keep > XML_CONTEXT_BYTES)
- keep = XML_CONTEXT_BYTES;
- neededSize += keep;
-#endif /* defined XML_CONTEXT_BYTES */
- if (neededSize <= bufferLim - buffer) {
-#ifdef XML_CONTEXT_BYTES
- if (keep < bufferPtr - buffer) {
- int offset = (int)(bufferPtr - buffer) - keep;
- memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
- bufferEnd -= offset;
- bufferPtr -= offset;
- }
-#else
- memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
- bufferEnd = buffer + (bufferEnd - bufferPtr);
- bufferPtr = buffer;
-#endif /* not defined XML_CONTEXT_BYTES */
- }
- else {
- char *newBuf;
- int bufferSize = (int)(bufferLim - bufferPtr);
- if (bufferSize == 0)
- bufferSize = INIT_BUFFER_SIZE;
- do {
- /* Do not invoke signed arithmetic overflow: */
- bufferSize = (int) (2U * (unsigned) bufferSize);
- } while (bufferSize < neededSize && bufferSize > 0);
- if (bufferSize <= 0) {
- errorCode = XML_ERROR_NO_MEMORY;
- return NULL;
- }
- newBuf = (char *)MALLOC(bufferSize);
- if (newBuf == 0) {
- errorCode = XML_ERROR_NO_MEMORY;
- return NULL;
- }
- bufferLim = newBuf + bufferSize;
-#ifdef XML_CONTEXT_BYTES
- if (bufferPtr) {
- int keep = (int)(bufferPtr - buffer);
- if (keep > XML_CONTEXT_BYTES)
- keep = XML_CONTEXT_BYTES;
- memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
- FREE(buffer);
- buffer = newBuf;
- bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
- bufferPtr = buffer + keep;
- }
- else {
- bufferEnd = newBuf + (bufferEnd - bufferPtr);
- bufferPtr = buffer = newBuf;
- }
-#else
- if (bufferPtr) {
- memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
- FREE(buffer);
- }
- bufferEnd = newBuf + (bufferEnd - bufferPtr);
- bufferPtr = buffer = newBuf;
-#endif /* not defined XML_CONTEXT_BYTES */
- }
- eventPtr = eventEndPtr = NULL;
- positionPtr = NULL;
- }
- return bufferEnd;
-}
-
-enum XML_Status XMLCALL
-XML_StopParser(XML_Parser parser, XML_Bool resumable)
-{
- switch (ps_parsing) {
- case XML_SUSPENDED:
- if (resumable) {
- errorCode = XML_ERROR_SUSPENDED;
- return XML_STATUS_ERROR;
- }
- ps_parsing = XML_FINISHED;
- break;
- case XML_FINISHED:
- errorCode = XML_ERROR_FINISHED;
- return XML_STATUS_ERROR;
- default:
- if (resumable) {
-#ifdef XML_DTD
- if (isParamEntity) {
- errorCode = XML_ERROR_SUSPEND_PE;
- return XML_STATUS_ERROR;
- }
-#endif
- ps_parsing = XML_SUSPENDED;
- }
- else
- ps_parsing = XML_FINISHED;
- }
- return XML_STATUS_OK;
-}
-
-enum XML_Status XMLCALL
-XML_ResumeParser(XML_Parser parser)
-{
- enum XML_Status result = XML_STATUS_OK;
-
- if (ps_parsing != XML_SUSPENDED) {
- errorCode = XML_ERROR_NOT_SUSPENDED;
- return XML_STATUS_ERROR;
- }
- ps_parsing = XML_PARSING;
-
- errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
-
- if (errorCode != XML_ERROR_NONE) {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
- else {
- switch (ps_parsing) {
- case XML_SUSPENDED:
- result = XML_STATUS_SUSPENDED;
- break;
- case XML_INITIALIZED:
- case XML_PARSING:
- if (ps_finalBuffer) {
- ps_parsing = XML_FINISHED;
- return result;
- }
- default: ;
- }
- }
-
- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
- positionPtr = bufferPtr;
- return result;
-}
-
-void XMLCALL
-XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
-{
- assert(status != NULL);
- *status = parser->m_parsingStatus;
-}
-
-enum XML_Error XMLCALL
-XML_GetErrorCode(XML_Parser parser)
-{
- return errorCode;
-}
-
-XML_Index XMLCALL
-XML_GetCurrentByteIndex(XML_Parser parser)
-{
- if (eventPtr)
- return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr));
- return -1;
-}
-
-int XMLCALL
-XML_GetCurrentByteCount(XML_Parser parser)
-{
- if (eventEndPtr && eventPtr)
- return (int)(eventEndPtr - eventPtr);
- return 0;
-}
-
-const char * XMLCALL
-XML_GetInputContext(XML_Parser parser, int *offset, int *size)
-{
-#ifdef XML_CONTEXT_BYTES
- if (eventPtr && buffer) {
- *offset = (int)(eventPtr - buffer);
- *size = (int)(bufferEnd - buffer);
- return buffer;
- }
-#endif /* defined XML_CONTEXT_BYTES */
- return (char *) 0;
-}
-
-XML_Size XMLCALL
-XML_GetCurrentLineNumber(XML_Parser parser)
-{
- if (eventPtr && eventPtr >= positionPtr) {
- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
- positionPtr = eventPtr;
- }
- return position.lineNumber + 1;
-}
-
-XML_Size XMLCALL
-XML_GetCurrentColumnNumber(XML_Parser parser)
-{
- if (eventPtr && eventPtr >= positionPtr) {
- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
- positionPtr = eventPtr;
- }
- return position.columnNumber;
-}
-
-void XMLCALL
-XML_FreeContentModel(XML_Parser parser, XML_Content *model)
-{
- FREE(model);
-}
-
-void * XMLCALL
-XML_MemMalloc(XML_Parser parser, size_t size)
-{
- return MALLOC(size);
-}
-
-void * XMLCALL
-XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
-{
- return REALLOC(ptr, size);
-}
-
-void XMLCALL
-XML_MemFree(XML_Parser parser, void *ptr)
-{
- FREE(ptr);
-}
-
-void XMLCALL
-XML_DefaultCurrent(XML_Parser parser)
-{
- if (defaultHandler) {
- if (openInternalEntities)
- reportDefault(parser,
- internalEncoding,
- openInternalEntities->internalEventPtr,
- openInternalEntities->internalEventEndPtr);
- else
- reportDefault(parser, encoding, eventPtr, eventEndPtr);
- }
-}
-
-const XML_LChar * XMLCALL
-XML_ErrorString(enum XML_Error code)
-{
- static const XML_LChar* const message[] = {
- 0,
- XML_L("out of memory"),
- XML_L("syntax error"),
- XML_L("no element found"),
- XML_L("not well-formed (invalid token)"),
- XML_L("unclosed token"),
- XML_L("partial character"),
- XML_L("mismatched tag"),
- XML_L("duplicate attribute"),
- XML_L("junk after document element"),
- XML_L("illegal parameter entity reference"),
- XML_L("undefined entity"),
- XML_L("recursive entity reference"),
- XML_L("asynchronous entity"),
- XML_L("reference to invalid character number"),
- XML_L("reference to binary entity"),
- XML_L("reference to external entity in attribute"),
- XML_L("XML or text declaration not at start of entity"),
- XML_L("unknown encoding"),
- XML_L("encoding specified in XML declaration is incorrect"),
- XML_L("unclosed CDATA section"),
- XML_L("error in processing external entity reference"),
- XML_L("document is not standalone"),
- XML_L("unexpected parser state - please send a bug report"),
- XML_L("entity declared in parameter entity"),
- XML_L("requested feature requires XML_DTD support in Expat"),
- XML_L("cannot change setting once parsing has begun"),
- XML_L("unbound prefix"),
- XML_L("must not undeclare prefix"),
- XML_L("incomplete markup in parameter entity"),
- XML_L("XML declaration not well-formed"),
- XML_L("text declaration not well-formed"),
- XML_L("illegal character(s) in public id"),
- XML_L("parser suspended"),
- XML_L("parser not suspended"),
- XML_L("parsing aborted"),
- XML_L("parsing finished"),
- XML_L("cannot suspend in external parameter entity"),
- XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
- XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
- XML_L("prefix must not be bound to one of the reserved namespace names")
- };
- if (code > 0 && code < sizeof(message)/sizeof(message[0]))
- return message[code];
- return NULL;
-}
-
-const XML_LChar * XMLCALL
-XML_ExpatVersion(void) {
-
- /* V1 is used to string-ize the version number. However, it would
- string-ize the actual version macro *names* unless we get them
- substituted before being passed to V1. CPP is defined to expand
- a macro, then rescan for more expansions. Thus, we use V2 to expand
- the version macros, then CPP will expand the resulting V1() macro
- with the correct numerals. */
- /* ### I'm assuming cpp is portable in this respect... */
-
-#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
-#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
-
- return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
-
-#undef V1
-#undef V2
-}
-
-XML_Expat_Version XMLCALL
-XML_ExpatVersionInfo(void)
-{
- XML_Expat_Version version;
-
- version.major = XML_MAJOR_VERSION;
- version.minor = XML_MINOR_VERSION;
- version.micro = XML_MICRO_VERSION;
-
- return version;
-}
-
-const XML_Feature * XMLCALL
-XML_GetFeatureList(void)
-{
- static const XML_Feature features[] = {
- {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
- sizeof(XML_Char)},
- {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
- sizeof(XML_LChar)},
-#ifdef XML_UNICODE
- {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
-#endif
-#ifdef XML_UNICODE_WCHAR_T
- {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
-#endif
-#ifdef XML_DTD
- {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
-#endif
-#ifdef XML_CONTEXT_BYTES
- {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
- XML_CONTEXT_BYTES},
-#endif
-#ifdef XML_MIN_SIZE
- {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
-#endif
-#ifdef XML_NS
- {XML_FEATURE_NS, XML_L("XML_NS"), 0},
-#endif
-#ifdef XML_LARGE_SIZE
- {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
-#endif
-#ifdef XML_ATTR_INFO
- {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
-#endif
- {XML_FEATURE_END, NULL, 0}
- };
-
- return features;
-}
-
-/* Initially tag->rawName always points into the parse buffer;
- for those TAG instances opened while the current parse buffer was
- processed, and not yet closed, we need to store tag->rawName in a more
- permanent location, since the parse buffer is about to be discarded.
-*/
-static XML_Bool
-storeRawNames(XML_Parser parser)
-{
- TAG *tag = tagStack;
- while (tag) {
- int bufSize;
- int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
- char *rawNameBuf = tag->buf + nameLen;
- /* Stop if already stored. Since tagStack is a stack, we can stop
- at the first entry that has already been copied; everything
- below it in the stack is already been accounted for in a
- previous call to this function.
- */
- if (tag->rawName == rawNameBuf)
- break;
- /* For re-use purposes we need to ensure that the
- size of tag->buf is a multiple of sizeof(XML_Char).
- */
- bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
- if (bufSize > tag->bufEnd - tag->buf) {
- char *temp = (char *)REALLOC(tag->buf, bufSize);
- if (temp == NULL)
- return XML_FALSE;
- /* if tag->name.str points to tag->buf (only when namespace
- processing is off) then we have to update it
- */
- if (tag->name.str == (XML_Char *)tag->buf)
- tag->name.str = (XML_Char *)temp;
- /* if tag->name.localPart is set (when namespace processing is on)
- then update it as well, since it will always point into tag->buf
- */
- if (tag->name.localPart)
- tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
- (XML_Char *)tag->buf);
- tag->buf = temp;
- tag->bufEnd = temp + bufSize;
- rawNameBuf = temp + nameLen;
- }
- memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
- tag->rawName = rawNameBuf;
- tag = tag->parent;
- }
- return XML_TRUE;
-}
-
-static enum XML_Error PTRCALL
-contentProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result = doContent(parser, 0, encoding, start, end,
- endPtr, (XML_Bool)!ps_finalBuffer);
- if (result == XML_ERROR_NONE) {
- if (!storeRawNames(parser))
- return XML_ERROR_NO_MEMORY;
- }
- return result;
-}
-
-static enum XML_Error PTRCALL
-externalEntityInitProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result = initializeEncoding(parser);
- if (result != XML_ERROR_NONE)
- return result;
- processor = externalEntityInitProcessor2;
- return externalEntityInitProcessor2(parser, start, end, endPtr);
-}
-
-static enum XML_Error PTRCALL
-externalEntityInitProcessor2(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- const char *next = start; /* XmlContentTok doesn't always set the last arg */
- int tok = XmlContentTok(encoding, start, end, &next);
- switch (tok) {
- case XML_TOK_BOM:
- /* If we are at the end of the buffer, this would cause the next stage,
- i.e. externalEntityInitProcessor3, to pass control directly to
- doContent (by detecting XML_TOK_NONE) without processing any xml text
- declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
- */
- if (next == end && !ps_finalBuffer) {
- *endPtr = next;
- return XML_ERROR_NONE;
- }
- start = next;
- break;
- case XML_TOK_PARTIAL:
- if (!ps_finalBuffer) {
- *endPtr = start;
- return XML_ERROR_NONE;
- }
- eventPtr = start;
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (!ps_finalBuffer) {
- *endPtr = start;
- return XML_ERROR_NONE;
- }
- eventPtr = start;
- return XML_ERROR_PARTIAL_CHAR;
- }
- processor = externalEntityInitProcessor3;
- return externalEntityInitProcessor3(parser, start, end, endPtr);
-}
-
-static enum XML_Error PTRCALL
-externalEntityInitProcessor3(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- int tok;
- const char *next = start; /* XmlContentTok doesn't always set the last arg */
- eventPtr = start;
- tok = XmlContentTok(encoding, start, end, &next);
- eventEndPtr = next;
-
- switch (tok) {
- case XML_TOK_XML_DECL:
- {
- enum XML_Error result;
- result = processXmlDecl(parser, 1, start, next);
- if (result != XML_ERROR_NONE)
- return result;
- switch (ps_parsing) {
- case XML_SUSPENDED:
- *endPtr = next;
- return XML_ERROR_NONE;
- case XML_FINISHED:
- return XML_ERROR_ABORTED;
- default:
- start = next;
- }
- }
- break;
- case XML_TOK_PARTIAL:
- if (!ps_finalBuffer) {
- *endPtr = start;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (!ps_finalBuffer) {
- *endPtr = start;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_PARTIAL_CHAR;
- }
- processor = externalEntityContentProcessor;
- tagLevel = 1;
- return externalEntityContentProcessor(parser, start, end, endPtr);
-}
-
-static enum XML_Error PTRCALL
-externalEntityContentProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result = doContent(parser, 1, encoding, start, end,
- endPtr, (XML_Bool)!ps_finalBuffer);
- if (result == XML_ERROR_NONE) {
- if (!storeRawNames(parser))
- return XML_ERROR_NO_MEMORY;
- }
- return result;
-}
-
-static enum XML_Error
-doContent(XML_Parser parser,
- int startTagLevel,
- const ENCODING *enc,
- const char *s,
- const char *end,
- const char **nextPtr,
- XML_Bool haveMore)
-{
- /* save one level of indirection */
- DTD * const dtd = _dtd;
-
- const char **eventPP;
- const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- *eventPP = s;
-
- for (;;) {
- const char *next = s; /* XmlContentTok doesn't always set the last arg */
- int tok = XmlContentTok(enc, s, end, &next);
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_TRAILING_CR:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- *eventEndPP = end;
- if (characterDataHandler) {
- XML_Char c = 0xA;
- characterDataHandler(handlerArg, &c, 1);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, end);
- /* We are at the end of the final buffer, should we check for
- XML_SUSPENDED, XML_FINISHED?
- */
- if (startTagLevel == 0)
- return XML_ERROR_NO_ELEMENTS;
- if (tagLevel != startTagLevel)
- return XML_ERROR_ASYNC_ENTITY;
- *nextPtr = end;
- return XML_ERROR_NONE;
- case XML_TOK_NONE:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- if (startTagLevel > 0) {
- if (tagLevel != startTagLevel)
- return XML_ERROR_ASYNC_ENTITY;
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_NO_ELEMENTS;
- case XML_TOK_INVALID:
- *eventPP = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_ENTITY_REF:
- {
- const XML_Char *name;
- ENTITY *entity;
- XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (ch) {
- if (characterDataHandler)
- characterDataHandler(handlerArg, &ch, 1);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- name = poolStoreString(&dtd->pool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
- poolDiscard(&dtd->pool);
- /* First, determine if a check for an existing declaration is needed;
- if yes, check that the entity exists, and that it is internal,
- otherwise call the skipped entity or default handler.
- */
- if (!dtd->hasParamEntityRefs || dtd->standalone) {
- if (!entity)
- return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
- }
- else if (!entity) {
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, name, 0);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- if (entity->open)
- return XML_ERROR_RECURSIVE_ENTITY_REF;
- if (entity->notation)
- return XML_ERROR_BINARY_ENTITY_REF;
- if (entity->textPtr) {
- enum XML_Error result;
- if (!defaultExpandInternalEntities) {
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, entity->name, 0);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- result = processInternalEntity(parser, entity, XML_FALSE);
- if (result != XML_ERROR_NONE)
- return result;
- }
- else if (externalEntityRefHandler) {
- const XML_Char *context;
- entity->open = XML_TRUE;
- context = getContext(parser);
- entity->open = XML_FALSE;
- if (!context)
- return XML_ERROR_NO_MEMORY;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- context,
- entity->base,
- entity->systemId,
- entity->publicId))
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- poolDiscard(&tempPool);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- case XML_TOK_START_TAG_NO_ATTS:
- /* fall through */
- case XML_TOK_START_TAG_WITH_ATTS:
- {
- TAG *tag;
- enum XML_Error result;
- XML_Char *toPtr;
- if (freeTagList) {
- tag = freeTagList;
- freeTagList = freeTagList->parent;
- }
- else {
- tag = (TAG *)MALLOC(sizeof(TAG));
- if (!tag)
- return XML_ERROR_NO_MEMORY;
- tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
- if (!tag->buf) {
- FREE(tag);
- return XML_ERROR_NO_MEMORY;
- }
- tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
- }
- tag->bindings = NULL;
- tag->parent = tagStack;
- tagStack = tag;
- tag->name.localPart = NULL;
- tag->name.prefix = NULL;
- tag->rawName = s + enc->minBytesPerChar;
- tag->rawNameLength = XmlNameLength(enc, tag->rawName);
- ++tagLevel;
- {
- const char *rawNameEnd = tag->rawName + tag->rawNameLength;
- const char *fromPtr = tag->rawName;
- toPtr = (XML_Char *)tag->buf;
- for (;;) {
- int bufSize;
- int convLen;
- const enum XML_Convert_Result convert_res = XmlConvert(enc,
- &fromPtr, rawNameEnd,
- (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
- convLen = (int)(toPtr - (XML_Char *)tag->buf);
- if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
- tag->name.strLen = convLen;
- break;
- }
- bufSize = (int)(tag->bufEnd - tag->buf) << 1;
- {
- char *temp = (char *)REALLOC(tag->buf, bufSize);
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- tag->buf = temp;
- tag->bufEnd = temp + bufSize;
- toPtr = (XML_Char *)temp + convLen;
- }
- }
- }
- tag->name.str = (XML_Char *)tag->buf;
- *toPtr = XML_T('\0');
- result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
- if (result)
- return result;
- if (startElementHandler)
- startElementHandler(handlerArg, tag->name.str,
- (const XML_Char **)atts);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- poolClear(&tempPool);
- break;
- }
- case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
- /* fall through */
- case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
- {
- const char *rawName = s + enc->minBytesPerChar;
- enum XML_Error result;
- BINDING *bindings = NULL;
- XML_Bool noElmHandlers = XML_TRUE;
- TAG_NAME name;
- name.str = poolStoreString(&tempPool, enc, rawName,
- rawName + XmlNameLength(enc, rawName));
- if (!name.str)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- result = storeAtts(parser, enc, s, &name, &bindings);
- if (result)
- return result;
- poolFinish(&tempPool);
- if (startElementHandler) {
- startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
- noElmHandlers = XML_FALSE;
- }
- if (endElementHandler) {
- if (startElementHandler)
- *eventPP = *eventEndPP;
- endElementHandler(handlerArg, name.str);
- noElmHandlers = XML_FALSE;
- }
- if (noElmHandlers && defaultHandler)
- reportDefault(parser, enc, s, next);
- poolClear(&tempPool);
- while (bindings) {
- BINDING *b = bindings;
- if (endNamespaceDeclHandler)
- endNamespaceDeclHandler(handlerArg, b->prefix->name);
- bindings = bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- b->prefix->binding = b->prevPrefixBinding;
- }
- }
- if (tagLevel == 0)
- return epilogProcessor(parser, next, end, nextPtr);
- break;
- case XML_TOK_END_TAG:
- if (tagLevel == startTagLevel)
- return XML_ERROR_ASYNC_ENTITY;
- else {
- int len;
- const char *rawName;
- TAG *tag = tagStack;
- tagStack = tag->parent;
- tag->parent = freeTagList;
- freeTagList = tag;
- rawName = s + enc->minBytesPerChar*2;
- len = XmlNameLength(enc, rawName);
- if (len != tag->rawNameLength
- || memcmp(tag->rawName, rawName, len) != 0) {
- *eventPP = rawName;
- return XML_ERROR_TAG_MISMATCH;
- }
- --tagLevel;
- if (endElementHandler) {
- const XML_Char *localPart;
- const XML_Char *prefix;
- XML_Char *uri;
- localPart = tag->name.localPart;
- if (ns && localPart) {
- /* localPart and prefix may have been overwritten in
- tag->name.str, since this points to the binding->uri
- buffer which gets re-used; so we have to add them again
- */
- uri = (XML_Char *)tag->name.str + tag->name.uriLen;
- /* don't need to check for space - already done in storeAtts() */
- while (*localPart) *uri++ = *localPart++;
- prefix = (XML_Char *)tag->name.prefix;
- if (ns_triplets && prefix) {
- *uri++ = namespaceSeparator;
- while (*prefix) *uri++ = *prefix++;
- }
- *uri = XML_T('\0');
- }
- endElementHandler(handlerArg, tag->name.str);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- while (tag->bindings) {
- BINDING *b = tag->bindings;
- if (endNamespaceDeclHandler)
- endNamespaceDeclHandler(handlerArg, b->prefix->name);
- tag->bindings = tag->bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- b->prefix->binding = b->prevPrefixBinding;
- }
- if (tagLevel == 0)
- return epilogProcessor(parser, next, end, nextPtr);
- }
- break;
- case XML_TOK_CHAR_REF:
- {
- int n = XmlCharRefNumber(enc, s);
- if (n < 0)
- return XML_ERROR_BAD_CHAR_REF;
- if (characterDataHandler) {
- XML_Char buf[XML_ENCODE_MAX];
- characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- }
- break;
- case XML_TOK_XML_DECL:
- return XML_ERROR_MISPLACED_XML_PI;
- case XML_TOK_DATA_NEWLINE:
- if (characterDataHandler) {
- XML_Char c = 0xA;
- characterDataHandler(handlerArg, &c, 1);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- case XML_TOK_CDATA_SECT_OPEN:
- {
- enum XML_Error result;
- if (startCdataSectionHandler)
- startCdataSectionHandler(handlerArg);
-#if 0
- /* Suppose you doing a transformation on a document that involves
- changing only the character data. You set up a defaultHandler
- and a characterDataHandler. The defaultHandler simply copies
- characters through. The characterDataHandler does the
- transformation and writes the characters out escaping them as
- necessary. This case will fail to work if we leave out the
- following two lines (because & and < inside CDATA sections will
- be incorrectly escaped).
-
- However, now we have a start/endCdataSectionHandler, so it seems
- easier to let the user deal with this.
- */
- else if (characterDataHandler)
- characterDataHandler(handlerArg, dataBuf, 0);
-#endif
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
- if (result != XML_ERROR_NONE)
- return result;
- else if (!next) {
- processor = cdataSectionProcessor;
- return result;
- }
- }
- break;
- case XML_TOK_TRAILING_RSQB:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- if (characterDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
- characterDataHandler(handlerArg, dataBuf,
- (int)(dataPtr - (ICHAR *)dataBuf));
- }
- else
- characterDataHandler(handlerArg,
- (XML_Char *)s,
- (int)((XML_Char *)end - (XML_Char *)s));
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, end);
- /* We are at the end of the final buffer, should we check for
- XML_SUSPENDED, XML_FINISHED?
- */
- if (startTagLevel == 0) {
- *eventPP = end;
- return XML_ERROR_NO_ELEMENTS;
- }
- if (tagLevel != startTagLevel) {
- *eventPP = end;
- return XML_ERROR_ASYNC_ENTITY;
- }
- *nextPtr = end;
- return XML_ERROR_NONE;
- case XML_TOK_DATA_CHARS:
- {
- XML_CharacterDataHandler charDataHandler = characterDataHandler;
- if (charDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- for (;;) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
- *eventEndPP = s;
- charDataHandler(handlerArg, dataBuf,
- (int)(dataPtr - (ICHAR *)dataBuf));
- if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
- break;
- *eventPP = s;
- }
- }
- else
- charDataHandler(handlerArg,
- (XML_Char *)s,
- (int)((XML_Char *)next - (XML_Char *)s));
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- }
- break;
- case XML_TOK_PI:
- if (!reportProcessingInstruction(parser, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- break;
- case XML_TOK_COMMENT:
- if (!reportComment(parser, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- break;
- default:
- if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- *eventPP = s = next;
- switch (ps_parsing) {
- case XML_SUSPENDED:
- *nextPtr = next;
- return XML_ERROR_NONE;
- case XML_FINISHED:
- return XML_ERROR_ABORTED;
- default: ;
- }
- }
- /* not reached */
-}
-
-/* Precondition: all arguments must be non-NULL;
- Purpose:
- - normalize attributes
- - check attributes for well-formedness
- - generate namespace aware attribute names (URI, prefix)
- - build list of attributes for startElementHandler
- - default attributes
- - process namespace declarations (check and report them)
- - generate namespace aware element name (URI, prefix)
-*/
-static enum XML_Error
-storeAtts(XML_Parser parser, const ENCODING *enc,
- const char *attStr, TAG_NAME *tagNamePtr,
- BINDING **bindingsPtr)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
- ELEMENT_TYPE *elementType;
- int nDefaultAtts;
- const XML_Char **appAtts; /* the attribute list for the application */
- int attIndex = 0;
- int prefixLen;
- int i;
- int n;
- XML_Char *uri;
- int nPrefixes = 0;
- BINDING *binding;
- const XML_Char *localPart;
-
- /* lookup the element type name */
- elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
- if (!elementType) {
- const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
- sizeof(ELEMENT_TYPE));
- if (!elementType)
- return XML_ERROR_NO_MEMORY;
- if (ns && !setElementTypePrefix(parser, elementType))
- return XML_ERROR_NO_MEMORY;
- }
- nDefaultAtts = elementType->nDefaultAtts;
-
- /* get the attributes from the tokenizer */
- n = XmlGetAttributes(enc, attStr, attsSize, atts);
- if (n + nDefaultAtts > attsSize) {
- int oldAttsSize = attsSize;
- ATTRIBUTE *temp;
-#ifdef XML_ATTR_INFO
- XML_AttrInfo *temp2;
-#endif
- attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
- temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- atts = temp;
-#ifdef XML_ATTR_INFO
- temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
- if (temp2 == NULL)
- return XML_ERROR_NO_MEMORY;
- attInfo = temp2;
-#endif
- if (n > oldAttsSize)
- XmlGetAttributes(enc, attStr, n, atts);
- }
-
- appAtts = (const XML_Char **)atts;
- for (i = 0; i < n; i++) {
- ATTRIBUTE *currAtt = &atts[i];
-#ifdef XML_ATTR_INFO
- XML_AttrInfo *currAttInfo = &attInfo[i];
-#endif
- /* add the name and value to the attribute list */
- ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
- currAtt->name
- + XmlNameLength(enc, currAtt->name));
- if (!attId)
- return XML_ERROR_NO_MEMORY;
-#ifdef XML_ATTR_INFO
- currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);
- currAttInfo->nameEnd = currAttInfo->nameStart +
- XmlNameLength(enc, currAtt->name);
- currAttInfo->valueStart = parseEndByteIndex -
- (parseEndPtr - currAtt->valuePtr);
- currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);
-#endif
- /* Detect duplicate attributes by their QNames. This does not work when
- namespace processing is turned on and different prefixes for the same
- namespace are used. For this case we have a check further down.
- */
- if ((attId->name)[-1]) {
- if (enc == encoding)
- eventPtr = atts[i].name;
- return XML_ERROR_DUPLICATE_ATTRIBUTE;
- }
- (attId->name)[-1] = 1;
- appAtts[attIndex++] = attId->name;
- if (!atts[i].normalized) {
- enum XML_Error result;
- XML_Bool isCdata = XML_TRUE;
-
- /* figure out whether declared as other than CDATA */
- if (attId->maybeTokenized) {
- int j;
- for (j = 0; j < nDefaultAtts; j++) {
- if (attId == elementType->defaultAtts[j].id) {
- isCdata = elementType->defaultAtts[j].isCdata;
- break;
- }
- }
- }
-
- /* normalize the attribute value */
- result = storeAttributeValue(parser, enc, isCdata,
- atts[i].valuePtr, atts[i].valueEnd,
- &tempPool);
- if (result)
- return result;
- appAtts[attIndex] = poolStart(&tempPool);
- poolFinish(&tempPool);
- }
- else {
- /* the value did not need normalizing */
- appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
- atts[i].valueEnd);
- if (appAtts[attIndex] == 0)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- }
- /* handle prefixed attribute names */
- if (attId->prefix) {
- if (attId->xmlns) {
- /* deal with namespace declarations here */
- enum XML_Error result = addBinding(parser, attId->prefix, attId,
- appAtts[attIndex], bindingsPtr);
- if (result)
- return result;
- --attIndex;
- }
- else {
- /* deal with other prefixed names later */
- attIndex++;
- nPrefixes++;
- (attId->name)[-1] = 2;
- }
- }
- else
- attIndex++;
- }
-
- /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
- nSpecifiedAtts = attIndex;
- if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
- for (i = 0; i < attIndex; i += 2)
- if (appAtts[i] == elementType->idAtt->name) {
- idAttIndex = i;
- break;
- }
- }
- else
- idAttIndex = -1;
-
- /* do attribute defaulting */
- for (i = 0; i < nDefaultAtts; i++) {
- const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
- if (!(da->id->name)[-1] && da->value) {
- if (da->id->prefix) {
- if (da->id->xmlns) {
- enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
- da->value, bindingsPtr);
- if (result)
- return result;
- }
- else {
- (da->id->name)[-1] = 2;
- nPrefixes++;
- appAtts[attIndex++] = da->id->name;
- appAtts[attIndex++] = da->value;
- }
- }
- else {
- (da->id->name)[-1] = 1;
- appAtts[attIndex++] = da->id->name;
- appAtts[attIndex++] = da->value;
- }
- }
- }
- appAtts[attIndex] = 0;
-
- /* expand prefixed attribute names, check for duplicates,
- and clear flags that say whether attributes were specified */
- i = 0;
- if (nPrefixes) {
- int j; /* hash table index */
- unsigned long version = nsAttsVersion;
- int nsAttsSize = (int)1 << nsAttsPower;
- /* size of hash table must be at least 2 * (# of prefixed attributes) */
- if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
- NS_ATT *temp;
- /* hash table size must also be a power of 2 and >= 8 */
- while (nPrefixes >> nsAttsPower++);
- if (nsAttsPower < 3)
- nsAttsPower = 3;
- nsAttsSize = (int)1 << nsAttsPower;
- temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
- if (!temp)
- return XML_ERROR_NO_MEMORY;
- nsAtts = temp;
- version = 0; /* force re-initialization of nsAtts hash table */
- }
- /* using a version flag saves us from initializing nsAtts every time */
- if (!version) { /* initialize version flags when version wraps around */
- version = INIT_ATTS_VERSION;
- for (j = nsAttsSize; j != 0; )
- nsAtts[--j].version = version;
- }
- nsAttsVersion = --version;
-
- /* expand prefixed names and check for duplicates */
- for (; i < attIndex; i += 2) {
- const XML_Char *s = appAtts[i];
- if (s[-1] == 2) { /* prefixed */
- ATTRIBUTE_ID *id;
- const BINDING *b;
- unsigned long uriHash = hash_secret_salt;
- ((XML_Char *)s)[-1] = 0; /* clear flag */
- id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
- if (!id || !id->prefix)
- return XML_ERROR_NO_MEMORY;
- b = id->prefix->binding;
- if (!b)
- return XML_ERROR_UNBOUND_PREFIX;
-
- /* as we expand the name we also calculate its hash value */
- for (j = 0; j < b->uriLen; j++) {
- const XML_Char c = b->uri[j];
- if (!poolAppendChar(&tempPool, c))
- return XML_ERROR_NO_MEMORY;
- uriHash = CHAR_HASH(uriHash, c);
- }
- while (*s++ != XML_T(ASCII_COLON))
- ;
- do { /* copies null terminator */
- const XML_Char c = *s;
- if (!poolAppendChar(&tempPool, *s))
- return XML_ERROR_NO_MEMORY;
- uriHash = CHAR_HASH(uriHash, c);
- } while (*s++);
-
- { /* Check hash table for duplicate of expanded name (uriName).
- Derived from code in lookup(parser, HASH_TABLE *table, ...).
- */
- unsigned char step = 0;
- unsigned long mask = nsAttsSize - 1;
- j = uriHash & mask; /* index into hash table */
- while (nsAtts[j].version == version) {
- /* for speed we compare stored hash values first */
- if (uriHash == nsAtts[j].hash) {
- const XML_Char *s1 = poolStart(&tempPool);
- const XML_Char *s2 = nsAtts[j].uriName;
- /* s1 is null terminated, but not s2 */
- for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
- if (*s1 == 0)
- return XML_ERROR_DUPLICATE_ATTRIBUTE;
- }
- if (!step)
- step = PROBE_STEP(uriHash, mask, nsAttsPower);
- j < step ? (j += nsAttsSize - step) : (j -= step);
- }
- }
-
- if (ns_triplets) { /* append namespace separator and prefix */
- tempPool.ptr[-1] = namespaceSeparator;
- s = b->prefix->name;
- do {
- if (!poolAppendChar(&tempPool, *s))
- return XML_ERROR_NO_MEMORY;
- } while (*s++);
- }
-
- /* store expanded name in attribute list */
- s = poolStart(&tempPool);
- poolFinish(&tempPool);
- appAtts[i] = s;
-
- /* fill empty slot with new version, uriName and hash value */
- nsAtts[j].version = version;
- nsAtts[j].hash = uriHash;
- nsAtts[j].uriName = s;
-
- if (!--nPrefixes) {
- i += 2;
- break;
- }
- }
- else /* not prefixed */
- ((XML_Char *)s)[-1] = 0; /* clear flag */
- }
- }
- /* clear flags for the remaining attributes */
- for (; i < attIndex; i += 2)
- ((XML_Char *)(appAtts[i]))[-1] = 0;
- for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
- binding->attId->name[-1] = 0;
-
- if (!ns)
- return XML_ERROR_NONE;
-
- /* expand the element type name */
- if (elementType->prefix) {
- binding = elementType->prefix->binding;
- if (!binding)
- return XML_ERROR_UNBOUND_PREFIX;
- localPart = tagNamePtr->str;
- while (*localPart++ != XML_T(ASCII_COLON))
- ;
- }
- else if (dtd->defaultPrefix.binding) {
- binding = dtd->defaultPrefix.binding;
- localPart = tagNamePtr->str;
- }
- else
- return XML_ERROR_NONE;
- prefixLen = 0;
- if (ns_triplets && binding->prefix->name) {
- for (; binding->prefix->name[prefixLen++];)
- ; /* prefixLen includes null terminator */
- }
- tagNamePtr->localPart = localPart;
- tagNamePtr->uriLen = binding->uriLen;
- tagNamePtr->prefix = binding->prefix->name;
- tagNamePtr->prefixLen = prefixLen;
- for (i = 0; localPart[i++];)
- ; /* i includes null terminator */
- n = i + binding->uriLen + prefixLen;
- if (n > binding->uriAlloc) {
- TAG *p;
- uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
- if (!uri)
- return XML_ERROR_NO_MEMORY;
- binding->uriAlloc = n + EXPAND_SPARE;
- memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
- for (p = tagStack; p; p = p->parent)
- if (p->name.str == binding->uri)
- p->name.str = uri;
- FREE(binding->uri);
- binding->uri = uri;
- }
- /* if namespaceSeparator != '\0' then uri includes it already */
- uri = binding->uri + binding->uriLen;
- memcpy(uri, localPart, i * sizeof(XML_Char));
- /* we always have a namespace separator between localPart and prefix */
- if (prefixLen) {
- uri += i - 1;
- *uri = namespaceSeparator; /* replace null terminator */
- memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
- }
- tagNamePtr->str = binding->uri;
- return XML_ERROR_NONE;
-}
-
-/* addBinding() overwrites the value of prefix->binding without checking.
- Therefore one must keep track of the old value outside of addBinding().
-*/
-static enum XML_Error
-addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
- const XML_Char *uri, BINDING **bindingsPtr)
-{
- static const XML_Char xmlNamespace[] = {
- ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
- ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
- ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
- ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
- ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
- ASCII_e, '\0'
- };
- static const int xmlLen =
- (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
- static const XML_Char xmlnsNamespace[] = {
- ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
- ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
- ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
- ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
- ASCII_SLASH, '\0'
- };
- static const int xmlnsLen =
- (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
-
- XML_Bool mustBeXML = XML_FALSE;
- XML_Bool isXML = XML_TRUE;
- XML_Bool isXMLNS = XML_TRUE;
-
- BINDING *b;
- int len;
-
- /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
- if (*uri == XML_T('\0') && prefix->name)
- return XML_ERROR_UNDECLARING_PREFIX;
-
- if (prefix->name
- && prefix->name[0] == XML_T(ASCII_x)
- && prefix->name[1] == XML_T(ASCII_m)
- && prefix->name[2] == XML_T(ASCII_l)) {
-
- /* Not allowed to bind xmlns */
- if (prefix->name[3] == XML_T(ASCII_n)
- && prefix->name[4] == XML_T(ASCII_s)
- && prefix->name[5] == XML_T('\0'))
- return XML_ERROR_RESERVED_PREFIX_XMLNS;
-
- if (prefix->name[3] == XML_T('\0'))
- mustBeXML = XML_TRUE;
- }
-
- for (len = 0; uri[len]; len++) {
- if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
- isXML = XML_FALSE;
-
- if (!mustBeXML && isXMLNS
- && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
- isXMLNS = XML_FALSE;
- }
- isXML = isXML && len == xmlLen;
- isXMLNS = isXMLNS && len == xmlnsLen;
-
- if (mustBeXML != isXML)
- return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
- : XML_ERROR_RESERVED_NAMESPACE_URI;
-
- if (isXMLNS)
- return XML_ERROR_RESERVED_NAMESPACE_URI;
-
- if (namespaceSeparator)
- len++;
- if (freeBindingList) {
- b = freeBindingList;
- if (len > b->uriAlloc) {
- XML_Char *temp = (XML_Char *)REALLOC(b->uri,
- sizeof(XML_Char) * (len + EXPAND_SPARE));
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- b->uri = temp;
- b->uriAlloc = len + EXPAND_SPARE;
- }
- freeBindingList = b->nextTagBinding;
- }
- else {
- b = (BINDING *)MALLOC(sizeof(BINDING));
- if (!b)
- return XML_ERROR_NO_MEMORY;
- b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
- if (!b->uri) {
- FREE(b);
- return XML_ERROR_NO_MEMORY;
- }
- b->uriAlloc = len + EXPAND_SPARE;
- }
- b->uriLen = len;
- memcpy(b->uri, uri, len * sizeof(XML_Char));
- if (namespaceSeparator)
- b->uri[len - 1] = namespaceSeparator;
- b->prefix = prefix;
- b->attId = attId;
- b->prevPrefixBinding = prefix->binding;
- /* NULL binding when default namespace undeclared */
- if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
- prefix->binding = NULL;
- else
- prefix->binding = b;
- b->nextTagBinding = *bindingsPtr;
- *bindingsPtr = b;
- /* if attId == NULL then we are not starting a namespace scope */
- if (attId && startNamespaceDeclHandler)
- startNamespaceDeclHandler(handlerArg, prefix->name,
- prefix->binding ? uri : 0);
- return XML_ERROR_NONE;
-}
-
-/* The idea here is to avoid using stack for each CDATA section when
- the whole file is parsed with one call.
-*/
-static enum XML_Error PTRCALL
-cdataSectionProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result = doCdataSection(parser, encoding, &start, end,
- endPtr, (XML_Bool)!ps_finalBuffer);
- if (result != XML_ERROR_NONE)
- return result;
- if (start) {
- if (parentParser) { /* we are parsing an external entity */
- processor = externalEntityContentProcessor;
- return externalEntityContentProcessor(parser, start, end, endPtr);
- }
- else {
- processor = contentProcessor;
- return contentProcessor(parser, start, end, endPtr);
- }
- }
- return result;
-}
-
-/* startPtr gets set to non-null if the section is closed, and to null if
- the section is not yet closed.
-*/
-static enum XML_Error
-doCdataSection(XML_Parser parser,
- const ENCODING *enc,
- const char **startPtr,
- const char *end,
- const char **nextPtr,
- XML_Bool haveMore)
-{
- const char *s = *startPtr;
- const char **eventPP;
- const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- *eventPP = s;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- *eventPP = s;
- *startPtr = NULL;
-
- for (;;) {
- const char *next;
- int tok = XmlCdataSectionTok(enc, s, end, &next);
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_CDATA_SECT_CLOSE:
- if (endCdataSectionHandler)
- endCdataSectionHandler(handlerArg);
-#if 0
- /* see comment under XML_TOK_CDATA_SECT_OPEN */
- else if (characterDataHandler)
- characterDataHandler(handlerArg, dataBuf, 0);
-#endif
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- *startPtr = next;
- *nextPtr = next;
- if (ps_parsing == XML_FINISHED)
- return XML_ERROR_ABORTED;
- else
- return XML_ERROR_NONE;
- case XML_TOK_DATA_NEWLINE:
- if (characterDataHandler) {
- XML_Char c = 0xA;
- characterDataHandler(handlerArg, &c, 1);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- case XML_TOK_DATA_CHARS:
- {
- XML_CharacterDataHandler charDataHandler = characterDataHandler;
- if (charDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- for (;;) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
- *eventEndPP = next;
- charDataHandler(handlerArg, dataBuf,
- (int)(dataPtr - (ICHAR *)dataBuf));
- if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
- break;
- *eventPP = s;
- }
- }
- else
- charDataHandler(handlerArg,
- (XML_Char *)s,
- (int)((XML_Char *)next - (XML_Char *)s));
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- }
- break;
- case XML_TOK_INVALID:
- *eventPP = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_PARTIAL:
- case XML_TOK_NONE:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_UNCLOSED_CDATA_SECTION;
- default:
- *eventPP = next;
- return XML_ERROR_UNEXPECTED_STATE;
- }
-
- *eventPP = s = next;
- switch (ps_parsing) {
- case XML_SUSPENDED:
- *nextPtr = next;
- return XML_ERROR_NONE;
- case XML_FINISHED:
- return XML_ERROR_ABORTED;
- default: ;
- }
- }
- /* not reached */
-}
-
-#ifdef XML_DTD
-
-/* The idea here is to avoid using stack for each IGNORE section when
- the whole file is parsed with one call.
-*/
-static enum XML_Error PTRCALL
-ignoreSectionProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
- endPtr, (XML_Bool)!ps_finalBuffer);
- if (result != XML_ERROR_NONE)
- return result;
- if (start) {
- processor = prologProcessor;
- return prologProcessor(parser, start, end, endPtr);
- }
- return result;
-}
-
-/* startPtr gets set to non-null is the section is closed, and to null
- if the section is not yet closed.
-*/
-static enum XML_Error
-doIgnoreSection(XML_Parser parser,
- const ENCODING *enc,
- const char **startPtr,
- const char *end,
- const char **nextPtr,
- XML_Bool haveMore)
-{
- const char *next;
- int tok;
- const char *s = *startPtr;
- const char **eventPP;
- const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- *eventPP = s;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- *eventPP = s;
- *startPtr = NULL;
- tok = XmlIgnoreSectionTok(enc, s, end, &next);
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_IGNORE_SECT:
- if (defaultHandler)
- reportDefault(parser, enc, s, next);
- *startPtr = next;
- *nextPtr = next;
- if (ps_parsing == XML_FINISHED)
- return XML_ERROR_ABORTED;
- else
- return XML_ERROR_NONE;
- case XML_TOK_INVALID:
- *eventPP = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_PARTIAL:
- case XML_TOK_NONE:
- if (haveMore) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
- default:
- *eventPP = next;
- return XML_ERROR_UNEXPECTED_STATE;
- }
- /* not reached */
-}
-
-#endif /* XML_DTD */
-
-static enum XML_Error
-initializeEncoding(XML_Parser parser)
-{
- const char *s;
-#ifdef XML_UNICODE
- char encodingBuf[128];
- if (!protocolEncodingName)
- s = NULL;
- else {
- int i;
- for (i = 0; protocolEncodingName[i]; i++) {
- if (i == sizeof(encodingBuf) - 1
- || (protocolEncodingName[i] & ~0x7f) != 0) {
- encodingBuf[0] = '\0';
- break;
- }
- encodingBuf[i] = (char)protocolEncodingName[i];
- }
- encodingBuf[i] = '\0';
- s = encodingBuf;
- }
-#else
- s = protocolEncodingName;
-#endif
- if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
- return XML_ERROR_NONE;
- return handleUnknownEncoding(parser, protocolEncodingName);
-}
-
-static enum XML_Error
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
- const char *s, const char *next)
-{
- const char *encodingName = NULL;
- const XML_Char *storedEncName = NULL;
- const ENCODING *newEncoding = NULL;
- const char *version = NULL;
- const char *versionend;
- const XML_Char *storedversion = NULL;
- int standalone = -1;
- if (!(ns
- ? XmlParseXmlDeclNS
- : XmlParseXmlDecl)(isGeneralTextEntity,
- encoding,
- s,
- next,
- &eventPtr,
- &version,
- &versionend,
- &encodingName,
- &newEncoding,
- &standalone)) {
- if (isGeneralTextEntity)
- return XML_ERROR_TEXT_DECL;
- else
- return XML_ERROR_XML_DECL;
- }
- if (!isGeneralTextEntity && standalone == 1) {
- _dtd->standalone = XML_TRUE;
-#ifdef XML_DTD
- if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
-#endif /* XML_DTD */
- }
- if (xmlDeclHandler) {
- if (encodingName != NULL) {
- storedEncName = poolStoreString(&temp2Pool,
- encoding,
- encodingName,
- encodingName
- + XmlNameLength(encoding, encodingName));
- if (!storedEncName)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&temp2Pool);
- }
- if (version) {
- storedversion = poolStoreString(&temp2Pool,
- encoding,
- version,
- versionend - encoding->minBytesPerChar);
- if (!storedversion)
- return XML_ERROR_NO_MEMORY;
- }
- xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
- }
- else if (defaultHandler)
- reportDefault(parser, encoding, s, next);
- if (protocolEncodingName == NULL) {
- if (newEncoding) {
- if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
- eventPtr = encodingName;
- return XML_ERROR_INCORRECT_ENCODING;
- }
- encoding = newEncoding;
- }
- else if (encodingName) {
- enum XML_Error result;
- if (!storedEncName) {
- storedEncName = poolStoreString(
- &temp2Pool, encoding, encodingName,
- encodingName + XmlNameLength(encoding, encodingName));
- if (!storedEncName)
- return XML_ERROR_NO_MEMORY;
- }
- result = handleUnknownEncoding(parser, storedEncName);
- poolClear(&temp2Pool);
- if (result == XML_ERROR_UNKNOWN_ENCODING)
- eventPtr = encodingName;
- return result;
- }
- }
-
- if (storedEncName || storedversion)
- poolClear(&temp2Pool);
-
- return XML_ERROR_NONE;
-}
-
-static enum XML_Error
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
-{
- if (unknownEncodingHandler) {
- XML_Encoding info;
- int i;
- for (i = 0; i < 256; i++)
- info.map[i] = -1;
- info.convert = NULL;
- info.data = NULL;
- info.release = NULL;
- if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
- &info)) {
- ENCODING *enc;
- unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
- if (!unknownEncodingMem) {
- if (info.release)
- info.release(info.data);
- return XML_ERROR_NO_MEMORY;
- }
- enc = (ns
- ? XmlInitUnknownEncodingNS
- : XmlInitUnknownEncoding)(unknownEncodingMem,
- info.map,
- info.convert,
- info.data);
- if (enc) {
- unknownEncodingData = info.data;
- unknownEncodingRelease = info.release;
- encoding = enc;
- return XML_ERROR_NONE;
- }
- }
- if (info.release != NULL)
- info.release(info.data);
- }
- return XML_ERROR_UNKNOWN_ENCODING;
-}
-
-static enum XML_Error PTRCALL
-prologInitProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- enum XML_Error result = initializeEncoding(parser);
- if (result != XML_ERROR_NONE)
- return result;
- processor = prologProcessor;
- return prologProcessor(parser, s, end, nextPtr);
-}
-
-#ifdef XML_DTD
-
-static enum XML_Error PTRCALL
-externalParEntInitProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- enum XML_Error result = initializeEncoding(parser);
- if (result != XML_ERROR_NONE)
- return result;
-
- /* we know now that XML_Parse(Buffer) has been called,
- so we consider the external parameter entity read */
- _dtd->paramEntityRead = XML_TRUE;
-
- if (prologState.inEntityValue) {
- processor = entityValueInitProcessor;
- return entityValueInitProcessor(parser, s, end, nextPtr);
- }
- else {
- processor = externalParEntProcessor;
- return externalParEntProcessor(parser, s, end, nextPtr);
- }
-}
-
-static enum XML_Error PTRCALL
-entityValueInitProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- int tok;
- const char *start = s;
- const char *next = start;
- eventPtr = start;
-
- for (;;) {
- tok = XmlPrologTok(encoding, start, end, &next);
- eventEndPtr = next;
- if (tok <= 0) {
- if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE: /* start == end */
- default:
- break;
- }
- /* found end of entity value - can store it now */
- return storeEntityValue(parser, encoding, s, end);
- }
- else if (tok == XML_TOK_XML_DECL) {
- enum XML_Error result;
- result = processXmlDecl(parser, 0, start, next);
- if (result != XML_ERROR_NONE)
- return result;
- switch (ps_parsing) {
- case XML_SUSPENDED:
- *nextPtr = next;
- return XML_ERROR_NONE;
- case XML_FINISHED:
- return XML_ERROR_ABORTED;
- default:
- *nextPtr = next;
- }
- /* stop scanning for text declaration - we found one */
- processor = entityValueProcessor;
- return entityValueProcessor(parser, next, end, nextPtr);
- }
- /* If we are at the end of the buffer, this would cause XmlPrologTok to
- return XML_TOK_NONE on the next call, which would then cause the
- function to exit with *nextPtr set to s - that is what we want for other
- tokens, but not for the BOM - we would rather like to skip it;
- then, when this routine is entered the next time, XmlPrologTok will
- return XML_TOK_INVALID, since the BOM is still in the buffer
- */
- else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
- *nextPtr = next;
- return XML_ERROR_NONE;
- }
- start = next;
- eventPtr = start;
- }
-}
-
-static enum XML_Error PTRCALL
-externalParEntProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- const char *next = s;
- int tok;
-
- tok = XmlPrologTok(encoding, s, end, &next);
- if (tok <= 0) {
- if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE: /* start == end */
- default:
- break;
- }
- }
- /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
- However, when parsing an external subset, doProlog will not accept a BOM
- as valid, and report a syntax error, so we have to skip the BOM
- */
- else if (tok == XML_TOK_BOM) {
- s = next;
- tok = XmlPrologTok(encoding, s, end, &next);
- }
-
- processor = prologProcessor;
- return doProlog(parser, encoding, s, end, tok, next,
- nextPtr, (XML_Bool)!ps_finalBuffer);
-}
-
-static enum XML_Error PTRCALL
-entityValueProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- const char *start = s;
- const char *next = s;
- const ENCODING *enc = encoding;
- int tok;
-
- for (;;) {
- tok = XmlPrologTok(enc, start, end, &next);
- if (tok <= 0) {
- if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE: /* start == end */
- default:
- break;
- }
- /* found end of entity value - can store it now */
- return storeEntityValue(parser, enc, s, end);
- }
- start = next;
- }
-}
-
-#endif /* XML_DTD */
-
-static enum XML_Error PTRCALL
-prologProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- const char *next = s;
- int tok = XmlPrologTok(encoding, s, end, &next);
- return doProlog(parser, encoding, s, end, tok, next,
- nextPtr, (XML_Bool)!ps_finalBuffer);
-}
-
-static enum XML_Error
-doProlog(XML_Parser parser,
- const ENCODING *enc,
- const char *s,
- const char *end,
- int tok,
- const char *next,
- const char **nextPtr,
- XML_Bool haveMore)
-{
-#ifdef XML_DTD
- static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
-#endif /* XML_DTD */
- static const XML_Char atypeCDATA[] =
- { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
- static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
- static const XML_Char atypeIDREF[] =
- { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
- static const XML_Char atypeIDREFS[] =
- { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
- static const XML_Char atypeENTITY[] =
- { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
- static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
- ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
- static const XML_Char atypeNMTOKEN[] = {
- ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
- static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
- ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
- static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
- ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
- static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
- static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
-
- /* save one level of indirection */
- DTD * const dtd = _dtd;
-
- const char **eventPP;
- const char **eventEndPP;
- enum XML_Content_Quant quant;
-
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
-
- for (;;) {
- int role;
- XML_Bool handleDefault = XML_TRUE;
- *eventPP = s;
- *eventEndPP = next;
- if (tok <= 0) {
- if (haveMore && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- *eventPP = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return XML_ERROR_PARTIAL_CHAR;
- case -XML_TOK_PROLOG_S:
- tok = -tok;
- break;
- case XML_TOK_NONE:
-#ifdef XML_DTD
- /* for internal PE NOT referenced between declarations */
- if (enc != encoding && !openInternalEntities->betweenDecl) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- /* WFC: PE Between Declarations - must check that PE contains
- complete markup, not only for external PEs, but also for
- internal PEs if the reference occurs between declarations.
- */
- if (isParamEntity || enc != encoding) {
- if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
- == XML_ROLE_ERROR)
- return XML_ERROR_INCOMPLETE_PE;
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
-#endif /* XML_DTD */
- return XML_ERROR_NO_ELEMENTS;
- default:
- tok = -tok;
- next = end;
- break;
- }
- }
- role = XmlTokenRole(&prologState, tok, s, next, enc);
- switch (role) {
- case XML_ROLE_XML_DECL:
- {
- enum XML_Error result = processXmlDecl(parser, 0, s, next);
- if (result != XML_ERROR_NONE)
- return result;
- enc = encoding;
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_DOCTYPE_NAME:
- if (startDoctypeDeclHandler) {
- doctypeName = poolStoreString(&tempPool, enc, s, next);
- if (!doctypeName)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- doctypePubid = NULL;
- handleDefault = XML_FALSE;
- }
- doctypeSysid = NULL; /* always initialize to NULL */
- break;
- case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
- if (startDoctypeDeclHandler) {
- startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
- doctypePubid, 1);
- doctypeName = NULL;
- poolClear(&tempPool);
- handleDefault = XML_FALSE;
- }
- break;
-#ifdef XML_DTD
- case XML_ROLE_TEXT_DECL:
- {
- enum XML_Error result = processXmlDecl(parser, 1, s, next);
- if (result != XML_ERROR_NONE)
- return result;
- enc = encoding;
- handleDefault = XML_FALSE;
- }
- break;
-#endif /* XML_DTD */
- case XML_ROLE_DOCTYPE_PUBLIC_ID:
-#ifdef XML_DTD
- useForeignDTD = XML_FALSE;
- declEntity = (ENTITY *)lookup(parser,
- &dtd->paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
-#endif /* XML_DTD */
- dtd->hasParamEntityRefs = XML_TRUE;
- if (startDoctypeDeclHandler) {
- XML_Char *pubId;
- if (!XmlIsPublicId(enc, s, next, eventPP))
- return XML_ERROR_PUBLICID;
- pubId = poolStoreString(&tempPool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!pubId)
- return XML_ERROR_NO_MEMORY;
- normalizePublicId(pubId);
- poolFinish(&tempPool);
- doctypePubid = pubId;
- handleDefault = XML_FALSE;
- goto alreadyChecked;
- }
- /* fall through */
- case XML_ROLE_ENTITY_PUBLIC_ID:
- if (!XmlIsPublicId(enc, s, next, eventPP))
- return XML_ERROR_PUBLICID;
- alreadyChecked:
- if (dtd->keepProcessing && declEntity) {
- XML_Char *tem = poolStoreString(&dtd->pool,
- enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!tem)
- return XML_ERROR_NO_MEMORY;
- normalizePublicId(tem);
- declEntity->publicId = tem;
- poolFinish(&dtd->pool);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_DOCTYPE_CLOSE:
- if (doctypeName) {
- startDoctypeDeclHandler(handlerArg, doctypeName,
- doctypeSysid, doctypePubid, 0);
- poolClear(&tempPool);
- handleDefault = XML_FALSE;
- }
- /* doctypeSysid will be non-NULL in the case of a previous
- XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
- was not set, indicating an external subset
- */
-#ifdef XML_DTD
- if (doctypeSysid || useForeignDTD) {
- XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
- dtd->hasParamEntityRefs = XML_TRUE;
- if (paramEntityParsing && externalEntityRefHandler) {
- ENTITY *entity = (ENTITY *)lookup(parser,
- &dtd->paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!entity)
- return XML_ERROR_NO_MEMORY;
- if (useForeignDTD)
- entity->base = curBase;
- dtd->paramEntityRead = XML_FALSE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId))
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- if (dtd->paramEntityRead) {
- if (!dtd->standalone &&
- notStandaloneHandler &&
- !notStandaloneHandler(handlerArg))
- return XML_ERROR_NOT_STANDALONE;
- }
- /* if we didn't read the foreign DTD then this means that there
- is no external subset and we must reset dtd->hasParamEntityRefs
- */
- else if (!doctypeSysid)
- dtd->hasParamEntityRefs = hadParamEntityRefs;
- /* end of DTD - no need to update dtd->keepProcessing */
- }
- useForeignDTD = XML_FALSE;
- }
-#endif /* XML_DTD */
- if (endDoctypeDeclHandler) {
- endDoctypeDeclHandler(handlerArg);
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_INSTANCE_START:
-#ifdef XML_DTD
- /* if there is no DOCTYPE declaration then now is the
- last chance to read the foreign DTD
- */
- if (useForeignDTD) {
- XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
- dtd->hasParamEntityRefs = XML_TRUE;
- if (paramEntityParsing && externalEntityRefHandler) {
- ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!entity)
- return XML_ERROR_NO_MEMORY;
- entity->base = curBase;
- dtd->paramEntityRead = XML_FALSE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId))
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- if (dtd->paramEntityRead) {
- if (!dtd->standalone &&
- notStandaloneHandler &&
- !notStandaloneHandler(handlerArg))
- return XML_ERROR_NOT_STANDALONE;
- }
- /* if we didn't read the foreign DTD then this means that there
- is no external subset and we must reset dtd->hasParamEntityRefs
- */
- else
- dtd->hasParamEntityRefs = hadParamEntityRefs;
- /* end of DTD - no need to update dtd->keepProcessing */
- }
- }
-#endif /* XML_DTD */
- processor = contentProcessor;
- return contentProcessor(parser, s, end, nextPtr);
- case XML_ROLE_ATTLIST_ELEMENT_NAME:
- declElementType = getElementType(parser, enc, s, next);
- if (!declElementType)
- return XML_ERROR_NO_MEMORY;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_NAME:
- declAttributeId = getAttributeId(parser, enc, s, next);
- if (!declAttributeId)
- return XML_ERROR_NO_MEMORY;
- declAttributeIsCdata = XML_FALSE;
- declAttributeType = NULL;
- declAttributeIsId = XML_FALSE;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
- declAttributeIsCdata = XML_TRUE;
- declAttributeType = atypeCDATA;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_ID:
- declAttributeIsId = XML_TRUE;
- declAttributeType = atypeID;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
- declAttributeType = atypeIDREF;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
- declAttributeType = atypeIDREFS;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
- declAttributeType = atypeENTITY;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
- declAttributeType = atypeENTITIES;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
- declAttributeType = atypeNMTOKEN;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
- declAttributeType = atypeNMTOKENS;
- checkAttListDeclHandler:
- if (dtd->keepProcessing && attlistDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
- case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
- if (dtd->keepProcessing && attlistDeclHandler) {
- const XML_Char *prefix;
- if (declAttributeType) {
- prefix = enumValueSep;
- }
- else {
- prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
- ? notationPrefix
- : enumValueStart);
- }
- if (!poolAppendString(&tempPool, prefix))
- return XML_ERROR_NO_MEMORY;
- if (!poolAppend(&tempPool, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- declAttributeType = tempPool.start;
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
- case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
- if (dtd->keepProcessing) {
- if (!defineAttribute(declElementType, declAttributeId,
- declAttributeIsCdata, declAttributeIsId,
- 0, parser))
- return XML_ERROR_NO_MEMORY;
- if (attlistDeclHandler && declAttributeType) {
- if (*declAttributeType == XML_T(ASCII_LPAREN)
- || (*declAttributeType == XML_T(ASCII_N)
- && declAttributeType[1] == XML_T(ASCII_O))) {
- /* Enumerated or Notation type */
- if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
- || !poolAppendChar(&tempPool, XML_T('\0')))
- return XML_ERROR_NO_MEMORY;
- declAttributeType = tempPool.start;
- poolFinish(&tempPool);
- }
- *eventEndPP = s;
- attlistDeclHandler(handlerArg, declElementType->name,
- declAttributeId->name, declAttributeType,
- 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
- poolClear(&tempPool);
- handleDefault = XML_FALSE;
- }
- }
- break;
- case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
- case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
- if (dtd->keepProcessing) {
- const XML_Char *attVal;
- enum XML_Error result =
- storeAttributeValue(parser, enc, declAttributeIsCdata,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar,
- &dtd->pool);
- if (result)
- return result;
- attVal = poolStart(&dtd->pool);
- poolFinish(&dtd->pool);
- /* ID attributes aren't allowed to have a default */
- if (!defineAttribute(declElementType, declAttributeId,
- declAttributeIsCdata, XML_FALSE, attVal, parser))
- return XML_ERROR_NO_MEMORY;
- if (attlistDeclHandler && declAttributeType) {
- if (*declAttributeType == XML_T(ASCII_LPAREN)
- || (*declAttributeType == XML_T(ASCII_N)
- && declAttributeType[1] == XML_T(ASCII_O))) {
- /* Enumerated or Notation type */
- if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
- || !poolAppendChar(&tempPool, XML_T('\0')))
- return XML_ERROR_NO_MEMORY;
- declAttributeType = tempPool.start;
- poolFinish(&tempPool);
- }
- *eventEndPP = s;
- attlistDeclHandler(handlerArg, declElementType->name,
- declAttributeId->name, declAttributeType,
- attVal,
- role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
- poolClear(&tempPool);
- handleDefault = XML_FALSE;
- }
- }
- break;
- case XML_ROLE_ENTITY_VALUE:
- if (dtd->keepProcessing) {
- enum XML_Error result = storeEntityValue(parser, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (declEntity) {
- declEntity->textPtr = poolStart(&dtd->entityValuePool);
- declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
- poolFinish(&dtd->entityValuePool);
- if (entityDeclHandler) {
- *eventEndPP = s;
- entityDeclHandler(handlerArg,
- declEntity->name,
- declEntity->is_param,
- declEntity->textPtr,
- declEntity->textLen,
- curBase, 0, 0, 0);
- handleDefault = XML_FALSE;
- }
- }
- else
- poolDiscard(&dtd->entityValuePool);
- if (result != XML_ERROR_NONE)
- return result;
- }
- break;
- case XML_ROLE_DOCTYPE_SYSTEM_ID:
-#ifdef XML_DTD
- useForeignDTD = XML_FALSE;
-#endif /* XML_DTD */
- dtd->hasParamEntityRefs = XML_TRUE;
- if (startDoctypeDeclHandler) {
- doctypeSysid = poolStoreString(&tempPool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (doctypeSysid == NULL)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- handleDefault = XML_FALSE;
- }
-#ifdef XML_DTD
- else
- /* use externalSubsetName to make doctypeSysid non-NULL
- for the case where no startDoctypeDeclHandler is set */
- doctypeSysid = externalSubsetName;
-#endif /* XML_DTD */
- if (!dtd->standalone
-#ifdef XML_DTD
- && !paramEntityParsing
-#endif /* XML_DTD */
- && notStandaloneHandler
- && !notStandaloneHandler(handlerArg))
- return XML_ERROR_NOT_STANDALONE;
-#ifndef XML_DTD
- break;
-#else /* XML_DTD */
- if (!declEntity) {
- declEntity = (ENTITY *)lookup(parser,
- &dtd->paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
- declEntity->publicId = NULL;
- }
- /* fall through */
-#endif /* XML_DTD */
- case XML_ROLE_ENTITY_SYSTEM_ID:
- if (dtd->keepProcessing && declEntity) {
- declEntity->systemId = poolStoreString(&dtd->pool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!declEntity->systemId)
- return XML_ERROR_NO_MEMORY;
- declEntity->base = curBase;
- poolFinish(&dtd->pool);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_ENTITY_COMPLETE:
- if (dtd->keepProcessing && declEntity && entityDeclHandler) {
- *eventEndPP = s;
- entityDeclHandler(handlerArg,
- declEntity->name,
- declEntity->is_param,
- 0,0,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- 0);
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_ENTITY_NOTATION_NAME:
- if (dtd->keepProcessing && declEntity) {
- declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
- if (!declEntity->notation)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&dtd->pool);
- if (unparsedEntityDeclHandler) {
- *eventEndPP = s;
- unparsedEntityDeclHandler(handlerArg,
- declEntity->name,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- declEntity->notation);
- handleDefault = XML_FALSE;
- }
- else if (entityDeclHandler) {
- *eventEndPP = s;
- entityDeclHandler(handlerArg,
- declEntity->name,
- 0,0,0,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- declEntity->notation);
- handleDefault = XML_FALSE;
- }
- }
- break;
- case XML_ROLE_GENERAL_ENTITY_NAME:
- {
- if (XmlPredefinedEntityName(enc, s, next)) {
- declEntity = NULL;
- break;
- }
- if (dtd->keepProcessing) {
- const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
- sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
- if (declEntity->name != name) {
- poolDiscard(&dtd->pool);
- declEntity = NULL;
- }
- else {
- poolFinish(&dtd->pool);
- declEntity->publicId = NULL;
- declEntity->is_param = XML_FALSE;
- /* if we have a parent parser or are reading an internal parameter
- entity, then the entity declaration is not considered "internal"
- */
- declEntity->is_internal = !(parentParser || openInternalEntities);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- }
- else {
- poolDiscard(&dtd->pool);
- declEntity = NULL;
- }
- }
- break;
- case XML_ROLE_PARAM_ENTITY_NAME:
-#ifdef XML_DTD
- if (dtd->keepProcessing) {
- const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
- name, sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
- if (declEntity->name != name) {
- poolDiscard(&dtd->pool);
- declEntity = NULL;
- }
- else {
- poolFinish(&dtd->pool);
- declEntity->publicId = NULL;
- declEntity->is_param = XML_TRUE;
- /* if we have a parent parser or are reading an internal parameter
- entity, then the entity declaration is not considered "internal"
- */
- declEntity->is_internal = !(parentParser || openInternalEntities);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- }
- else {
- poolDiscard(&dtd->pool);
- declEntity = NULL;
- }
-#else /* not XML_DTD */
- declEntity = NULL;
-#endif /* XML_DTD */
- break;
- case XML_ROLE_NOTATION_NAME:
- declNotationPublicId = NULL;
- declNotationName = NULL;
- if (notationDeclHandler) {
- declNotationName = poolStoreString(&tempPool, enc, s, next);
- if (!declNotationName)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_NOTATION_PUBLIC_ID:
- if (!XmlIsPublicId(enc, s, next, eventPP))
- return XML_ERROR_PUBLICID;
- if (declNotationName) { /* means notationDeclHandler != NULL */
- XML_Char *tem = poolStoreString(&tempPool,
- enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!tem)
- return XML_ERROR_NO_MEMORY;
- normalizePublicId(tem);
- declNotationPublicId = tem;
- poolFinish(&tempPool);
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_NOTATION_SYSTEM_ID:
- if (declNotationName && notationDeclHandler) {
- const XML_Char *systemId
- = poolStoreString(&tempPool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!systemId)
- return XML_ERROR_NO_MEMORY;
- *eventEndPP = s;
- notationDeclHandler(handlerArg,
- declNotationName,
- curBase,
- systemId,
- declNotationPublicId);
- handleDefault = XML_FALSE;
- }
- poolClear(&tempPool);
- break;
- case XML_ROLE_NOTATION_NO_SYSTEM_ID:
- if (declNotationPublicId && notationDeclHandler) {
- *eventEndPP = s;
- notationDeclHandler(handlerArg,
- declNotationName,
- curBase,
- 0,
- declNotationPublicId);
- handleDefault = XML_FALSE;
- }
- poolClear(&tempPool);
- break;
- case XML_ROLE_ERROR:
- switch (tok) {
- case XML_TOK_PARAM_ENTITY_REF:
- /* PE references in internal subset are
- not allowed within declarations. */
- return XML_ERROR_PARAM_ENTITY_REF;
- case XML_TOK_XML_DECL:
- return XML_ERROR_MISPLACED_XML_PI;
- default:
- return XML_ERROR_SYNTAX;
- }
-#ifdef XML_DTD
- case XML_ROLE_IGNORE_SECT:
- {
- enum XML_Error result;
- if (defaultHandler)
- reportDefault(parser, enc, s, next);
- handleDefault = XML_FALSE;
- result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
- if (result != XML_ERROR_NONE)
- return result;
- else if (!next) {
- processor = ignoreSectionProcessor;
- return result;
- }
- }
- break;
-#endif /* XML_DTD */
- case XML_ROLE_GROUP_OPEN:
- if (prologState.level >= groupSize) {
- if (groupSize) {
- char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- groupConnector = temp;
- if (dtd->scaffIndex) {
- int *temp = (int *)REALLOC(dtd->scaffIndex,
- groupSize * sizeof(int));
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- dtd->scaffIndex = temp;
- }
- }
- else {
- groupConnector = (char *)MALLOC(groupSize = 32);
- if (!groupConnector)
- return XML_ERROR_NO_MEMORY;
- }
- }
- groupConnector[prologState.level] = 0;
- if (dtd->in_eldecl) {
- int myindex = nextScaffoldPart(parser);
- if (myindex < 0)
- return XML_ERROR_NO_MEMORY;
- dtd->scaffIndex[dtd->scaffLevel] = myindex;
- dtd->scaffLevel++;
- dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_GROUP_SEQUENCE:
- if (groupConnector[prologState.level] == ASCII_PIPE)
- return XML_ERROR_SYNTAX;
- groupConnector[prologState.level] = ASCII_COMMA;
- if (dtd->in_eldecl && elementDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_GROUP_CHOICE:
- if (groupConnector[prologState.level] == ASCII_COMMA)
- return XML_ERROR_SYNTAX;
- if (dtd->in_eldecl
- && !groupConnector[prologState.level]
- && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
- != XML_CTYPE_MIXED)
- ) {
- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
- = XML_CTYPE_CHOICE;
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- }
- groupConnector[prologState.level] = ASCII_PIPE;
- break;
- case XML_ROLE_PARAM_ENTITY_REF:
-#ifdef XML_DTD
- case XML_ROLE_INNER_PARAM_ENTITY_REF:
- dtd->hasParamEntityRefs = XML_TRUE;
- if (!paramEntityParsing)
- dtd->keepProcessing = dtd->standalone;
- else {
- const XML_Char *name;
- ENTITY *entity;
- name = poolStoreString(&dtd->pool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
- poolDiscard(&dtd->pool);
- /* first, determine if a check for an existing declaration is needed;
- if yes, check that the entity exists, and that it is internal,
- otherwise call the skipped entity handler
- */
- if (prologState.documentEntity &&
- (dtd->standalone
- ? !openInternalEntities
- : !dtd->hasParamEntityRefs)) {
- if (!entity)
- return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
- }
- else if (!entity) {
- dtd->keepProcessing = dtd->standalone;
- /* cannot report skipped entities in declarations */
- if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
- skippedEntityHandler(handlerArg, name, 1);
- handleDefault = XML_FALSE;
- }
- break;
- }
- if (entity->open)
- return XML_ERROR_RECURSIVE_ENTITY_REF;
- if (entity->textPtr) {
- enum XML_Error result;
- XML_Bool betweenDecl =
- (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
- result = processInternalEntity(parser, entity, betweenDecl);
- if (result != XML_ERROR_NONE)
- return result;
- handleDefault = XML_FALSE;
- break;
- }
- if (externalEntityRefHandler) {
- dtd->paramEntityRead = XML_FALSE;
- entity->open = XML_TRUE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId)) {
- entity->open = XML_FALSE;
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- }
- entity->open = XML_FALSE;
- handleDefault = XML_FALSE;
- if (!dtd->paramEntityRead) {
- dtd->keepProcessing = dtd->standalone;
- break;
- }
- }
- else {
- dtd->keepProcessing = dtd->standalone;
- break;
- }
- }
-#endif /* XML_DTD */
- if (!dtd->standalone &&
- notStandaloneHandler &&
- !notStandaloneHandler(handlerArg))
- return XML_ERROR_NOT_STANDALONE;
- break;
-
- /* Element declaration stuff */
-
- case XML_ROLE_ELEMENT_NAME:
- if (elementDeclHandler) {
- declElementType = getElementType(parser, enc, s, next);
- if (!declElementType)
- return XML_ERROR_NO_MEMORY;
- dtd->scaffLevel = 0;
- dtd->scaffCount = 0;
- dtd->in_eldecl = XML_TRUE;
- handleDefault = XML_FALSE;
- }
- break;
-
- case XML_ROLE_CONTENT_ANY:
- case XML_ROLE_CONTENT_EMPTY:
- if (dtd->in_eldecl) {
- if (elementDeclHandler) {
- XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
- if (!content)
- return XML_ERROR_NO_MEMORY;
- content->quant = XML_CQUANT_NONE;
- content->name = NULL;
- content->numchildren = 0;
- content->children = NULL;
- content->type = ((role == XML_ROLE_CONTENT_ANY) ?
- XML_CTYPE_ANY :
- XML_CTYPE_EMPTY);
- *eventEndPP = s;
- elementDeclHandler(handlerArg, declElementType->name, content);
- handleDefault = XML_FALSE;
- }
- dtd->in_eldecl = XML_FALSE;
- }
- break;
-
- case XML_ROLE_CONTENT_PCDATA:
- if (dtd->in_eldecl) {
- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
- = XML_CTYPE_MIXED;
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
-
- case XML_ROLE_CONTENT_ELEMENT:
- quant = XML_CQUANT_NONE;
- goto elementContent;
- case XML_ROLE_CONTENT_ELEMENT_OPT:
- quant = XML_CQUANT_OPT;
- goto elementContent;
- case XML_ROLE_CONTENT_ELEMENT_REP:
- quant = XML_CQUANT_REP;
- goto elementContent;
- case XML_ROLE_CONTENT_ELEMENT_PLUS:
- quant = XML_CQUANT_PLUS;
- elementContent:
- if (dtd->in_eldecl) {
- ELEMENT_TYPE *el;
- const XML_Char *name;
- int nameLen;
- const char *nxt = (quant == XML_CQUANT_NONE
- ? next
- : next - enc->minBytesPerChar);
- int myindex = nextScaffoldPart(parser);
- if (myindex < 0)
- return XML_ERROR_NO_MEMORY;
- dtd->scaffold[myindex].type = XML_CTYPE_NAME;
- dtd->scaffold[myindex].quant = quant;
- el = getElementType(parser, enc, s, nxt);
- if (!el)
- return XML_ERROR_NO_MEMORY;
- name = el->name;
- dtd->scaffold[myindex].name = name;
- nameLen = 0;
- for (; name[nameLen++]; );
- dtd->contentStringLen += nameLen;
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
-
- case XML_ROLE_GROUP_CLOSE:
- quant = XML_CQUANT_NONE;
- goto closeGroup;
- case XML_ROLE_GROUP_CLOSE_OPT:
- quant = XML_CQUANT_OPT;
- goto closeGroup;
- case XML_ROLE_GROUP_CLOSE_REP:
- quant = XML_CQUANT_REP;
- goto closeGroup;
- case XML_ROLE_GROUP_CLOSE_PLUS:
- quant = XML_CQUANT_PLUS;
- closeGroup:
- if (dtd->in_eldecl) {
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- dtd->scaffLevel--;
- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
- if (dtd->scaffLevel == 0) {
- if (!handleDefault) {
- XML_Content *model = build_model(parser);
- if (!model)
- return XML_ERROR_NO_MEMORY;
- *eventEndPP = s;
- elementDeclHandler(handlerArg, declElementType->name, model);
- }
- dtd->in_eldecl = XML_FALSE;
- dtd->contentStringLen = 0;
- }
- }
- break;
- /* End element declaration stuff */
-
- case XML_ROLE_PI:
- if (!reportProcessingInstruction(parser, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_COMMENT:
- if (!reportComment(parser, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_NONE:
- switch (tok) {
- case XML_TOK_BOM:
- handleDefault = XML_FALSE;
- break;
- }
- break;
- case XML_ROLE_DOCTYPE_NONE:
- if (startDoctypeDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_ENTITY_NONE:
- if (dtd->keepProcessing && entityDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_NOTATION_NONE:
- if (notationDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_ATTLIST_NONE:
- if (dtd->keepProcessing && attlistDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_ELEMENT_NONE:
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- break;
- } /* end of big switch */
-
- if (handleDefault && defaultHandler)
- reportDefault(parser, enc, s, next);
-
- switch (ps_parsing) {
- case XML_SUSPENDED:
- *nextPtr = next;
- return XML_ERROR_NONE;
- case XML_FINISHED:
- return XML_ERROR_ABORTED;
- default:
- s = next;
- tok = XmlPrologTok(enc, s, end, &next);
- }
- }
- /* not reached */
-}
-
-static enum XML_Error PTRCALL
-epilogProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- processor = epilogProcessor;
- eventPtr = s;
- for (;;) {
- const char *next = NULL;
- int tok = XmlPrologTok(encoding, s, end, &next);
- eventEndPtr = next;
- switch (tok) {
- /* report partial linebreak - it might be the last token */
- case -XML_TOK_PROLOG_S:
- if (defaultHandler) {
- reportDefault(parser, encoding, s, next);
- if (ps_parsing == XML_FINISHED)
- return XML_ERROR_ABORTED;
- }
- *nextPtr = next;
- return XML_ERROR_NONE;
- case XML_TOK_NONE:
- *nextPtr = s;
- return XML_ERROR_NONE;
- case XML_TOK_PROLOG_S:
- if (defaultHandler)
- reportDefault(parser, encoding, s, next);
- break;
- case XML_TOK_PI:
- if (!reportProcessingInstruction(parser, encoding, s, next))
- return XML_ERROR_NO_MEMORY;
- break;
- case XML_TOK_COMMENT:
- if (!reportComment(parser, encoding, s, next))
- return XML_ERROR_NO_MEMORY;
- break;
- case XML_TOK_INVALID:
- eventPtr = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- if (!ps_finalBuffer) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (!ps_finalBuffer) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_PARTIAL_CHAR;
- default:
- return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
- }
- eventPtr = s = next;
- switch (ps_parsing) {
- case XML_SUSPENDED:
- *nextPtr = next;
- return XML_ERROR_NONE;
- case XML_FINISHED:
- return XML_ERROR_ABORTED;
- default: ;
- }
- }
-}
-
-static enum XML_Error
-processInternalEntity(XML_Parser parser, ENTITY *entity,
- XML_Bool betweenDecl)
-{
- const char *textStart, *textEnd;
- const char *next;
- enum XML_Error result;
- OPEN_INTERNAL_ENTITY *openEntity;
-
- if (freeInternalEntities) {
- openEntity = freeInternalEntities;
- freeInternalEntities = openEntity->next;
- }
- else {
- openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
- if (!openEntity)
- return XML_ERROR_NO_MEMORY;
- }
- entity->open = XML_TRUE;
- entity->processed = 0;
- openEntity->next = openInternalEntities;
- openInternalEntities = openEntity;
- openEntity->entity = entity;
- openEntity->startTagLevel = tagLevel;
- openEntity->betweenDecl = betweenDecl;
- openEntity->internalEventPtr = NULL;
- openEntity->internalEventEndPtr = NULL;
- textStart = (char *)entity->textPtr;
- textEnd = (char *)(entity->textPtr + entity->textLen);
-
-#ifdef XML_DTD
- if (entity->is_param) {
- int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
- result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
- next, &next, XML_FALSE);
- }
- else
-#endif /* XML_DTD */
- result = doContent(parser, tagLevel, internalEncoding, textStart,
- textEnd, &next, XML_FALSE);
-
- if (result == XML_ERROR_NONE) {
- if (textEnd != next && ps_parsing == XML_SUSPENDED) {
- entity->processed = (int)(next - textStart);
- processor = internalEntityProcessor;
- }
- else {
- entity->open = XML_FALSE;
- openInternalEntities = openEntity->next;
- /* put openEntity back in list of free instances */
- openEntity->next = freeInternalEntities;
- freeInternalEntities = openEntity;
- }
- }
- return result;
-}
-
-static enum XML_Error PTRCALL
-internalEntityProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- ENTITY *entity;
- const char *textStart, *textEnd;
- const char *next;
- enum XML_Error result;
- OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
- if (!openEntity)
- return XML_ERROR_UNEXPECTED_STATE;
-
- entity = openEntity->entity;
- textStart = ((char *)entity->textPtr) + entity->processed;
- textEnd = (char *)(entity->textPtr + entity->textLen);
-
-#ifdef XML_DTD
- if (entity->is_param) {
- int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
- result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
- next, &next, XML_FALSE);
- }
- else
-#endif /* XML_DTD */
- result = doContent(parser, openEntity->startTagLevel, internalEncoding,
- textStart, textEnd, &next, XML_FALSE);
-
- if (result != XML_ERROR_NONE)
- return result;
- else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
- entity->processed = (int)(next - (char *)entity->textPtr);
- return result;
- }
- else {
- entity->open = XML_FALSE;
- openInternalEntities = openEntity->next;
- /* put openEntity back in list of free instances */
- openEntity->next = freeInternalEntities;
- freeInternalEntities = openEntity;
- }
-
-#ifdef XML_DTD
- if (entity->is_param) {
- int tok;
- processor = prologProcessor;
- tok = XmlPrologTok(encoding, s, end, &next);
- return doProlog(parser, encoding, s, end, tok, next, nextPtr,
- (XML_Bool)!ps_finalBuffer);
- }
- else
-#endif /* XML_DTD */
- {
- processor = contentProcessor;
- /* see externalEntityContentProcessor vs contentProcessor */
- return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
- nextPtr, (XML_Bool)!ps_finalBuffer);
- }
-}
-
-static enum XML_Error PTRCALL
-errorProcessor(XML_Parser parser,
- const char *UNUSED_P(s),
- const char *UNUSED_P(end),
- const char **UNUSED_P(nextPtr))
-{
- return errorCode;
-}
-
-static enum XML_Error
-storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
- const char *ptr, const char *end,
- STRING_POOL *pool)
-{
- enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
- end, pool);
- if (result)
- return result;
- if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
- poolChop(pool);
- if (!poolAppendChar(pool, XML_T('\0')))
- return XML_ERROR_NO_MEMORY;
- return XML_ERROR_NONE;
-}
-
-static enum XML_Error
-appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
- const char *ptr, const char *end,
- STRING_POOL *pool)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
- for (;;) {
- const char *next;
- int tok = XmlAttributeValueTok(enc, ptr, end, &next);
- switch (tok) {
- case XML_TOK_NONE:
- return XML_ERROR_NONE;
- case XML_TOK_INVALID:
- if (enc == encoding)
- eventPtr = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_CHAR_REF:
- {
- XML_Char buf[XML_ENCODE_MAX];
- int i;
- int n = XmlCharRefNumber(enc, ptr);
- if (n < 0) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_BAD_CHAR_REF;
- }
- if (!isCdata
- && n == 0x20 /* space */
- && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
- break;
- n = XmlEncode(n, (ICHAR *)buf);
- if (!n) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_BAD_CHAR_REF;
- }
- for (i = 0; i < n; i++) {
- if (!poolAppendChar(pool, buf[i]))
- return XML_ERROR_NO_MEMORY;
- }
- }
- break;
- case XML_TOK_DATA_CHARS:
- if (!poolAppend(pool, enc, ptr, next))
- return XML_ERROR_NO_MEMORY;
- break;
- case XML_TOK_TRAILING_CR:
- next = ptr + enc->minBytesPerChar;
- /* fall through */
- case XML_TOK_ATTRIBUTE_VALUE_S:
- case XML_TOK_DATA_NEWLINE:
- if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
- break;
- if (!poolAppendChar(pool, 0x20))
- return XML_ERROR_NO_MEMORY;
- break;
- case XML_TOK_ENTITY_REF:
- {
- const XML_Char *name;
- ENTITY *entity;
- char checkEntityDecl;
- XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
- ptr + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (ch) {
- if (!poolAppendChar(pool, ch))
- return XML_ERROR_NO_MEMORY;
- break;
- }
- name = poolStoreString(&temp2Pool, enc,
- ptr + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
- poolDiscard(&temp2Pool);
- /* First, determine if a check for an existing declaration is needed;
- if yes, check that the entity exists, and that it is internal.
- */
- if (pool == &dtd->pool) /* are we called from prolog? */
- checkEntityDecl =
-#ifdef XML_DTD
- prologState.documentEntity &&
-#endif /* XML_DTD */
- (dtd->standalone
- ? !openInternalEntities
- : !dtd->hasParamEntityRefs);
- else /* if (pool == &tempPool): we are called from content */
- checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
- if (checkEntityDecl) {
- if (!entity)
- return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
- }
- else if (!entity) {
- /* Cannot report skipped entity here - see comments on
- skippedEntityHandler.
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, name, 0);
- */
- /* Cannot call the default handler because this would be
- out of sync with the call to the startElementHandler.
- if ((pool == &tempPool) && defaultHandler)
- reportDefault(parser, enc, ptr, next);
- */
- break;
- }
- if (entity->open) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_RECURSIVE_ENTITY_REF;
- }
- if (entity->notation) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_BINARY_ENTITY_REF;
- }
- if (!entity->textPtr) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
- }
- else {
- enum XML_Error result;
- const XML_Char *textEnd = entity->textPtr + entity->textLen;
- entity->open = XML_TRUE;
- result = appendAttributeValue(parser, internalEncoding, isCdata,
- (char *)entity->textPtr,
- (char *)textEnd, pool);
- entity->open = XML_FALSE;
- if (result)
- return result;
- }
- }
- break;
- default:
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_UNEXPECTED_STATE;
- }
- ptr = next;
- }
- /* not reached */
-}
-
-static enum XML_Error
-storeEntityValue(XML_Parser parser,
- const ENCODING *enc,
- const char *entityTextPtr,
- const char *entityTextEnd)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
- STRING_POOL *pool = &(dtd->entityValuePool);
- enum XML_Error result = XML_ERROR_NONE;
-#ifdef XML_DTD
- int oldInEntityValue = prologState.inEntityValue;
- prologState.inEntityValue = 1;
-#endif /* XML_DTD */
- /* never return Null for the value argument in EntityDeclHandler,
- since this would indicate an external entity; therefore we
- have to make sure that entityValuePool.start is not null */
- if (!pool->blocks) {
- if (!poolGrow(pool))
- return XML_ERROR_NO_MEMORY;
- }
-
- for (;;) {
- const char *next;
- int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
- switch (tok) {
- case XML_TOK_PARAM_ENTITY_REF:
-#ifdef XML_DTD
- if (isParamEntity || enc != encoding) {
- const XML_Char *name;
- ENTITY *entity;
- name = poolStoreString(&tempPool, enc,
- entityTextPtr + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
- poolDiscard(&tempPool);
- if (!entity) {
- /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
- /* cannot report skipped entity here - see comments on
- skippedEntityHandler
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, name, 0);
- */
- dtd->keepProcessing = dtd->standalone;
- goto endEntityValue;
- }
- if (entity->open) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_RECURSIVE_ENTITY_REF;
- goto endEntityValue;
- }
- if (entity->systemId) {
- if (externalEntityRefHandler) {
- dtd->paramEntityRead = XML_FALSE;
- entity->open = XML_TRUE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId)) {
- entity->open = XML_FALSE;
- result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- goto endEntityValue;
- }
- entity->open = XML_FALSE;
- if (!dtd->paramEntityRead)
- dtd->keepProcessing = dtd->standalone;
- }
- else
- dtd->keepProcessing = dtd->standalone;
- }
- else {
- entity->open = XML_TRUE;
- result = storeEntityValue(parser,
- internalEncoding,
- (char *)entity->textPtr,
- (char *)(entity->textPtr
- + entity->textLen));
- entity->open = XML_FALSE;
- if (result)
- goto endEntityValue;
- }
- break;
- }
-#endif /* XML_DTD */
- /* In the internal subset, PE references are not legal
- within markup declarations, e.g entity values in this case. */
- eventPtr = entityTextPtr;
- result = XML_ERROR_PARAM_ENTITY_REF;
- goto endEntityValue;
- case XML_TOK_NONE:
- result = XML_ERROR_NONE;
- goto endEntityValue;
- case XML_TOK_ENTITY_REF:
- case XML_TOK_DATA_CHARS:
- if (!poolAppend(pool, enc, entityTextPtr, next)) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- break;
- case XML_TOK_TRAILING_CR:
- next = entityTextPtr + enc->minBytesPerChar;
- /* fall through */
- case XML_TOK_DATA_NEWLINE:
- if (pool->end == pool->ptr && !poolGrow(pool)) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- *(pool->ptr)++ = 0xA;
- break;
- case XML_TOK_CHAR_REF:
- {
- XML_Char buf[XML_ENCODE_MAX];
- int i;
- int n = XmlCharRefNumber(enc, entityTextPtr);
- if (n < 0) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_BAD_CHAR_REF;
- goto endEntityValue;
- }
- n = XmlEncode(n, (ICHAR *)buf);
- if (!n) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_BAD_CHAR_REF;
- goto endEntityValue;
- }
- for (i = 0; i < n; i++) {
- if (pool->end == pool->ptr && !poolGrow(pool)) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- *(pool->ptr)++ = buf[i];
- }
- }
- break;
- case XML_TOK_PARTIAL:
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_INVALID_TOKEN;
- goto endEntityValue;
- case XML_TOK_INVALID:
- if (enc == encoding)
- eventPtr = next;
- result = XML_ERROR_INVALID_TOKEN;
- goto endEntityValue;
- default:
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_UNEXPECTED_STATE;
- goto endEntityValue;
- }
- entityTextPtr = next;
- }
-endEntityValue:
-#ifdef XML_DTD
- prologState.inEntityValue = oldInEntityValue;
-#endif /* XML_DTD */
- return result;
-}
-
-static void FASTCALL
-normalizeLines(XML_Char *s)
-{
- XML_Char *p;
- for (;; s++) {
- if (*s == XML_T('\0'))
- return;
- if (*s == 0xD)
- break;
- }
- p = s;
- do {
- if (*s == 0xD) {
- *p++ = 0xA;
- if (*++s == 0xA)
- s++;
- }
- else
- *p++ = *s++;
- } while (*s);
- *p = XML_T('\0');
-}
-
-static int
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end)
-{
- const XML_Char *target;
- XML_Char *data;
- const char *tem;
- if (!processingInstructionHandler) {
- if (defaultHandler)
- reportDefault(parser, enc, start, end);
- return 1;
- }
- start += enc->minBytesPerChar * 2;
- tem = start + XmlNameLength(enc, start);
- target = poolStoreString(&tempPool, enc, start, tem);
- if (!target)
- return 0;
- poolFinish(&tempPool);
- data = poolStoreString(&tempPool, enc,
- XmlSkipS(enc, tem),
- end - enc->minBytesPerChar*2);
- if (!data)
- return 0;
- normalizeLines(data);
- processingInstructionHandler(handlerArg, target, data);
- poolClear(&tempPool);
- return 1;
-}
-
-static int
-reportComment(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end)
-{
- XML_Char *data;
- if (!commentHandler) {
- if (defaultHandler)
- reportDefault(parser, enc, start, end);
- return 1;
- }
- data = poolStoreString(&tempPool,
- enc,
- start + enc->minBytesPerChar * 4,
- end - enc->minBytesPerChar * 3);
- if (!data)
- return 0;
- normalizeLines(data);
- commentHandler(handlerArg, data);
- poolClear(&tempPool);
- return 1;
-}
-
-static void
-reportDefault(XML_Parser parser, const ENCODING *enc,
- const char *s, const char *end)
-{
- if (MUST_CONVERT(enc, s)) {
- enum XML_Convert_Result convert_res;
- const char **eventPP;
- const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- do {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
- *eventEndPP = s;
- defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
- *eventPP = s;
- } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
- }
- else
- defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
-}
-
-
-static int
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
- XML_Bool isId, const XML_Char *value, XML_Parser parser)
-{
- DEFAULT_ATTRIBUTE *att;
- if (value || isId) {
- /* The handling of default attributes gets messed up if we have
- a default which duplicates a non-default. */
- int i;
- for (i = 0; i < type->nDefaultAtts; i++)
- if (attId == type->defaultAtts[i].id)
- return 1;
- if (isId && !type->idAtt && !attId->xmlns)
- type->idAtt = attId;
- }
- if (type->nDefaultAtts == type->allocDefaultAtts) {
- if (type->allocDefaultAtts == 0) {
- type->allocDefaultAtts = 8;
- type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
- * sizeof(DEFAULT_ATTRIBUTE));
- if (!type->defaultAtts)
- return 0;
- }
- else {
- DEFAULT_ATTRIBUTE *temp;
- int count = type->allocDefaultAtts * 2;
- temp = (DEFAULT_ATTRIBUTE *)
- REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
- if (temp == NULL)
- return 0;
- type->allocDefaultAtts = count;
- type->defaultAtts = temp;
- }
- }
- att = type->defaultAtts + type->nDefaultAtts;
- att->id = attId;
- att->value = value;
- att->isCdata = isCdata;
- if (!isCdata)
- attId->maybeTokenized = XML_TRUE;
- type->nDefaultAtts += 1;
- return 1;
-}
-
-static int
-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
- const XML_Char *name;
- for (name = elementType->name; *name; name++) {
- if (*name == XML_T(ASCII_COLON)) {
- PREFIX *prefix;
- const XML_Char *s;
- for (s = elementType->name; s != name; s++) {
- if (!poolAppendChar(&dtd->pool, *s))
- return 0;
- }
- if (!poolAppendChar(&dtd->pool, XML_T('\0')))
- return 0;
- prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
- sizeof(PREFIX));
- if (!prefix)
- return 0;
- if (prefix->name == poolStart(&dtd->pool))
- poolFinish(&dtd->pool);
- else
- poolDiscard(&dtd->pool);
- elementType->prefix = prefix;
-
- }
- }
- return 1;
-}
-
-static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
- ATTRIBUTE_ID *id;
- const XML_Char *name;
- if (!poolAppendChar(&dtd->pool, XML_T('\0')))
- return NULL;
- name = poolStoreString(&dtd->pool, enc, start, end);
- if (!name)
- return NULL;
- /* skip quotation mark - its storage will be re-used (like in name[-1]) */
- ++name;
- id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
- if (!id)
- return NULL;
- if (id->name != name)
- poolDiscard(&dtd->pool);
- else {
- poolFinish(&dtd->pool);
- if (!ns)
- ;
- else if (name[0] == XML_T(ASCII_x)
- && name[1] == XML_T(ASCII_m)
- && name[2] == XML_T(ASCII_l)
- && name[3] == XML_T(ASCII_n)
- && name[4] == XML_T(ASCII_s)
- && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
- if (name[5] == XML_T('\0'))
- id->prefix = &dtd->defaultPrefix;
- else
- id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
- id->xmlns = XML_TRUE;
- }
- else {
- int i;
- for (i = 0; name[i]; i++) {
- /* attributes without prefix are *not* in the default namespace */
- if (name[i] == XML_T(ASCII_COLON)) {
- int j;
- for (j = 0; j < i; j++) {
- if (!poolAppendChar(&dtd->pool, name[j]))
- return NULL;
- }
- if (!poolAppendChar(&dtd->pool, XML_T('\0')))
- return NULL;
- id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
- sizeof(PREFIX));
- if (!id->prefix)
- return NULL;
- if (id->prefix->name == poolStart(&dtd->pool))
- poolFinish(&dtd->pool);
- else
- poolDiscard(&dtd->pool);
- break;
- }
- }
- }
- }
- return id;
-}
-
-#define CONTEXT_SEP XML_T(ASCII_FF)
-
-static const XML_Char *
-getContext(XML_Parser parser)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
- HASH_TABLE_ITER iter;
- XML_Bool needSep = XML_FALSE;
-
- if (dtd->defaultPrefix.binding) {
- int i;
- int len;
- if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
- return NULL;
- len = dtd->defaultPrefix.binding->uriLen;
- if (namespaceSeparator)
- len--;
- for (i = 0; i < len; i++)
- if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
- return NULL;
- needSep = XML_TRUE;
- }
-
- hashTableIterInit(&iter, &(dtd->prefixes));
- for (;;) {
- int i;
- int len;
- const XML_Char *s;
- PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
- if (!prefix)
- break;
- if (!prefix->binding)
- continue;
- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
- return NULL;
- for (s = prefix->name; *s; s++)
- if (!poolAppendChar(&tempPool, *s))
- return NULL;
- if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
- return NULL;
- len = prefix->binding->uriLen;
- if (namespaceSeparator)
- len--;
- for (i = 0; i < len; i++)
- if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
- return NULL;
- needSep = XML_TRUE;
- }
-
-
- hashTableIterInit(&iter, &(dtd->generalEntities));
- for (;;) {
- const XML_Char *s;
- ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
- if (!e)
- break;
- if (!e->open)
- continue;
- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
- return NULL;
- for (s = e->name; *s; s++)
- if (!poolAppendChar(&tempPool, *s))
- return 0;
- needSep = XML_TRUE;
- }
-
- if (!poolAppendChar(&tempPool, XML_T('\0')))
- return NULL;
- return tempPool.start;
-}
-
-static XML_Bool
-setContext(XML_Parser parser, const XML_Char *context)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
- const XML_Char *s = context;
-
- while (*context != XML_T('\0')) {
- if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
- ENTITY *e;
- if (!poolAppendChar(&tempPool, XML_T('\0')))
- return XML_FALSE;
- e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);
- if (e)
- e->open = XML_TRUE;
- if (*s != XML_T('\0'))
- s++;
- context = s;
- poolDiscard(&tempPool);
- }
- else if (*s == XML_T(ASCII_EQUALS)) {
- PREFIX *prefix;
- if (poolLength(&tempPool) == 0)
- prefix = &dtd->defaultPrefix;
- else {
- if (!poolAppendChar(&tempPool, XML_T('\0')))
- return XML_FALSE;
- prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),
- sizeof(PREFIX));
- if (!prefix)
- return XML_FALSE;
- if (prefix->name == poolStart(&tempPool)) {
- prefix->name = poolCopyString(&dtd->pool, prefix->name);
- if (!prefix->name)
- return XML_FALSE;
- }
- poolDiscard(&tempPool);
- }
- for (context = s + 1;
- *context != CONTEXT_SEP && *context != XML_T('\0');
- context++)
- if (!poolAppendChar(&tempPool, *context))
- return XML_FALSE;
- if (!poolAppendChar(&tempPool, XML_T('\0')))
- return XML_FALSE;
- if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
- &inheritedBindings) != XML_ERROR_NONE)
- return XML_FALSE;
- poolDiscard(&tempPool);
- if (*context != XML_T('\0'))
- ++context;
- s = context;
- }
- else {
- if (!poolAppendChar(&tempPool, *s))
- return XML_FALSE;
- s++;
- }
- }
- return XML_TRUE;
-}
-
-static void FASTCALL
-normalizePublicId(XML_Char *publicId)
-{
- XML_Char *p = publicId;
- XML_Char *s;
- for (s = publicId; *s; s++) {
- switch (*s) {
- case 0x20:
- case 0xD:
- case 0xA:
- if (p != publicId && p[-1] != 0x20)
- *p++ = 0x20;
- break;
- default:
- *p++ = *s;
- }
- }
- if (p != publicId && p[-1] == 0x20)
- --p;
- *p = XML_T('\0');
-}
-
-static DTD *
-dtdCreate(const XML_Memory_Handling_Suite *ms)
-{
- DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
- if (p == NULL)
- return p;
- poolInit(&(p->pool), ms);
- poolInit(&(p->entityValuePool), ms);
- hashTableInit(&(p->generalEntities), ms);
- hashTableInit(&(p->elementTypes), ms);
- hashTableInit(&(p->attributeIds), ms);
- hashTableInit(&(p->prefixes), ms);
-#ifdef XML_DTD
- p->paramEntityRead = XML_FALSE;
- hashTableInit(&(p->paramEntities), ms);
-#endif /* XML_DTD */
- p->defaultPrefix.name = NULL;
- p->defaultPrefix.binding = NULL;
-
- p->in_eldecl = XML_FALSE;
- p->scaffIndex = NULL;
- p->scaffold = NULL;
- p->scaffLevel = 0;
- p->scaffSize = 0;
- p->scaffCount = 0;
- p->contentStringLen = 0;
-
- p->keepProcessing = XML_TRUE;
- p->hasParamEntityRefs = XML_FALSE;
- p->standalone = XML_FALSE;
- return p;
-}
-
-static void
-dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
-{
- HASH_TABLE_ITER iter;
- hashTableIterInit(&iter, &(p->elementTypes));
- for (;;) {
- ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
- if (!e)
- break;
- if (e->allocDefaultAtts != 0)
- ms->free_fcn(e->defaultAtts);
- }
- hashTableClear(&(p->generalEntities));
-#ifdef XML_DTD
- p->paramEntityRead = XML_FALSE;
- hashTableClear(&(p->paramEntities));
-#endif /* XML_DTD */
- hashTableClear(&(p->elementTypes));
- hashTableClear(&(p->attributeIds));
- hashTableClear(&(p->prefixes));
- poolClear(&(p->pool));
- poolClear(&(p->entityValuePool));
- p->defaultPrefix.name = NULL;
- p->defaultPrefix.binding = NULL;
-
- p->in_eldecl = XML_FALSE;
-
- ms->free_fcn(p->scaffIndex);
- p->scaffIndex = NULL;
- ms->free_fcn(p->scaffold);
- p->scaffold = NULL;
-
- p->scaffLevel = 0;
- p->scaffSize = 0;
- p->scaffCount = 0;
- p->contentStringLen = 0;
-
- p->keepProcessing = XML_TRUE;
- p->hasParamEntityRefs = XML_FALSE;
- p->standalone = XML_FALSE;
-}
-
-static void
-dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
-{
- HASH_TABLE_ITER iter;
- hashTableIterInit(&iter, &(p->elementTypes));
- for (;;) {
- ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
- if (!e)
- break;
- if (e->allocDefaultAtts != 0)
- ms->free_fcn(e->defaultAtts);
- }
- hashTableDestroy(&(p->generalEntities));
-#ifdef XML_DTD
- hashTableDestroy(&(p->paramEntities));
-#endif /* XML_DTD */
- hashTableDestroy(&(p->elementTypes));
- hashTableDestroy(&(p->attributeIds));
- hashTableDestroy(&(p->prefixes));
- poolDestroy(&(p->pool));
- poolDestroy(&(p->entityValuePool));
- if (isDocEntity) {
- ms->free_fcn(p->scaffIndex);
- ms->free_fcn(p->scaffold);
- }
- ms->free_fcn(p);
-}
-
-/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
- The new DTD has already been initialized.
-*/
-static int
-dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
-{
- HASH_TABLE_ITER iter;
-
- /* Copy the prefix table. */
-
- hashTableIterInit(&iter, &(oldDtd->prefixes));
- for (;;) {
- const XML_Char *name;
- const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
- if (!oldP)
- break;
- name = poolCopyString(&(newDtd->pool), oldP->name);
- if (!name)
- return 0;
- if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
- return 0;
- }
-
- hashTableIterInit(&iter, &(oldDtd->attributeIds));
-
- /* Copy the attribute id table. */
-
- for (;;) {
- ATTRIBUTE_ID *newA;
- const XML_Char *name;
- const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
-
- if (!oldA)
- break;
- /* Remember to allocate the scratch byte before the name. */
- if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
- return 0;
- name = poolCopyString(&(newDtd->pool), oldA->name);
- if (!name)
- return 0;
- ++name;
- newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
- sizeof(ATTRIBUTE_ID));
- if (!newA)
- return 0;
- newA->maybeTokenized = oldA->maybeTokenized;
- if (oldA->prefix) {
- newA->xmlns = oldA->xmlns;
- if (oldA->prefix == &oldDtd->defaultPrefix)
- newA->prefix = &newDtd->defaultPrefix;
- else
- newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
- oldA->prefix->name, 0);
- }
- }
-
- /* Copy the element type table. */
-
- hashTableIterInit(&iter, &(oldDtd->elementTypes));
-
- for (;;) {
- int i;
- ELEMENT_TYPE *newE;
- const XML_Char *name;
- const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
- if (!oldE)
- break;
- name = poolCopyString(&(newDtd->pool), oldE->name);
- if (!name)
- return 0;
- newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
- sizeof(ELEMENT_TYPE));
- if (!newE)
- return 0;
- if (oldE->nDefaultAtts) {
- newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
- ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
- if (!newE->defaultAtts) {
- ms->free_fcn(newE);
- return 0;
- }
- }
- if (oldE->idAtt)
- newE->idAtt = (ATTRIBUTE_ID *)
- lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
- newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
- if (oldE->prefix)
- newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
- oldE->prefix->name, 0);
- for (i = 0; i < newE->nDefaultAtts; i++) {
- newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
- lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
- newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
- if (oldE->defaultAtts[i].value) {
- newE->defaultAtts[i].value
- = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
- if (!newE->defaultAtts[i].value)
- return 0;
- }
- else
- newE->defaultAtts[i].value = NULL;
- }
- }
-
- /* Copy the entity tables. */
- if (!copyEntityTable(oldParser,
- &(newDtd->generalEntities),
- &(newDtd->pool),
- &(oldDtd->generalEntities)))
- return 0;
-
-#ifdef XML_DTD
- if (!copyEntityTable(oldParser,
- &(newDtd->paramEntities),
- &(newDtd->pool),
- &(oldDtd->paramEntities)))
- return 0;
- newDtd->paramEntityRead = oldDtd->paramEntityRead;
-#endif /* XML_DTD */
-
- newDtd->keepProcessing = oldDtd->keepProcessing;
- newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
- newDtd->standalone = oldDtd->standalone;
-
- /* Don't want deep copying for scaffolding */
- newDtd->in_eldecl = oldDtd->in_eldecl;
- newDtd->scaffold = oldDtd->scaffold;
- newDtd->contentStringLen = oldDtd->contentStringLen;
- newDtd->scaffSize = oldDtd->scaffSize;
- newDtd->scaffLevel = oldDtd->scaffLevel;
- newDtd->scaffIndex = oldDtd->scaffIndex;
-
- return 1;
-} /* End dtdCopy */
-
-static int
-copyEntityTable(XML_Parser oldParser,
- HASH_TABLE *newTable,
- STRING_POOL *newPool,
- const HASH_TABLE *oldTable)
-{
- HASH_TABLE_ITER iter;
- const XML_Char *cachedOldBase = NULL;
- const XML_Char *cachedNewBase = NULL;
-
- hashTableIterInit(&iter, oldTable);
-
- for (;;) {
- ENTITY *newE;
- const XML_Char *name;
- const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
- if (!oldE)
- break;
- name = poolCopyString(newPool, oldE->name);
- if (!name)
- return 0;
- newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
- if (!newE)
- return 0;
- if (oldE->systemId) {
- const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
- if (!tem)
- return 0;
- newE->systemId = tem;
- if (oldE->base) {
- if (oldE->base == cachedOldBase)
- newE->base = cachedNewBase;
- else {
- cachedOldBase = oldE->base;
- tem = poolCopyString(newPool, cachedOldBase);
- if (!tem)
- return 0;
- cachedNewBase = newE->base = tem;
- }
- }
- if (oldE->publicId) {
- tem = poolCopyString(newPool, oldE->publicId);
- if (!tem)
- return 0;
- newE->publicId = tem;
- }
- }
- else {
- const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
- oldE->textLen);
- if (!tem)
- return 0;
- newE->textPtr = tem;
- newE->textLen = oldE->textLen;
- }
- if (oldE->notation) {
- const XML_Char *tem = poolCopyString(newPool, oldE->notation);
- if (!tem)
- return 0;
- newE->notation = tem;
- }
- newE->is_param = oldE->is_param;
- newE->is_internal = oldE->is_internal;
- }
- return 1;
-}
-
-#define INIT_POWER 6
-
-static XML_Bool FASTCALL
-keyeq(KEY s1, KEY s2)
-{
- for (; *s1 == *s2; s1++, s2++)
- if (*s1 == 0)
- return XML_TRUE;
- return XML_FALSE;
-}
-
-static unsigned long FASTCALL
-hash(XML_Parser parser, KEY s)
-{
- unsigned long h = hash_secret_salt;
- while (*s)
- h = CHAR_HASH(h, *s++);
- return h;
-}
-
-static NAMED *
-lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
-{
- size_t i;
- if (table->size == 0) {
- size_t tsize;
- if (!createSize)
- return NULL;
- table->power = INIT_POWER;
- /* table->size is a power of 2 */
- table->size = (size_t)1 << INIT_POWER;
- tsize = table->size * sizeof(NAMED *);
- table->v = (NAMED **)table->mem->malloc_fcn(tsize);
- if (!table->v) {
- table->size = 0;
- return NULL;
- }
- memset(table->v, 0, tsize);
- i = hash(parser, name) & ((unsigned long)table->size - 1);
- }
- else {
- unsigned long h = hash(parser, name);
- unsigned long mask = (unsigned long)table->size - 1;
- unsigned char step = 0;
- i = h & mask;
- while (table->v[i]) {
- if (keyeq(name, table->v[i]->name))
- return table->v[i];
- if (!step)
- step = PROBE_STEP(h, mask, table->power);
- i < step ? (i += table->size - step) : (i -= step);
- }
- if (!createSize)
- return NULL;
-
- /* check for overflow (table is half full) */
- if (table->used >> (table->power - 1)) {
- unsigned char newPower = table->power + 1;
- size_t newSize = (size_t)1 << newPower;
- unsigned long newMask = (unsigned long)newSize - 1;
- size_t tsize = newSize * sizeof(NAMED *);
- NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
- if (!newV)
- return NULL;
- memset(newV, 0, tsize);
- for (i = 0; i < table->size; i++)
- if (table->v[i]) {
- unsigned long newHash = hash(parser, table->v[i]->name);
- size_t j = newHash & newMask;
- step = 0;
- while (newV[j]) {
- if (!step)
- step = PROBE_STEP(newHash, newMask, newPower);
- j < step ? (j += newSize - step) : (j -= step);
- }
- newV[j] = table->v[i];
- }
- table->mem->free_fcn(table->v);
- table->v = newV;
- table->power = newPower;
- table->size = newSize;
- i = h & newMask;
- step = 0;
- while (table->v[i]) {
- if (!step)
- step = PROBE_STEP(h, newMask, newPower);
- i < step ? (i += newSize - step) : (i -= step);
- }
- }
- }
- table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
- if (!table->v[i])
- return NULL;
- memset(table->v[i], 0, createSize);
- table->v[i]->name = name;
- (table->used)++;
- return table->v[i];
-}
-
-static void FASTCALL
-hashTableClear(HASH_TABLE *table)
-{
- size_t i;
- for (i = 0; i < table->size; i++) {
- table->mem->free_fcn(table->v[i]);
- table->v[i] = NULL;
- }
- table->used = 0;
-}
-
-static void FASTCALL
-hashTableDestroy(HASH_TABLE *table)
-{
- size_t i;
- for (i = 0; i < table->size; i++)
- table->mem->free_fcn(table->v[i]);
- table->mem->free_fcn(table->v);
-}
-
-static void FASTCALL
-hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
-{
- p->power = 0;
- p->size = 0;
- p->used = 0;
- p->v = NULL;
- p->mem = ms;
-}
-
-static void FASTCALL
-hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
-{
- iter->p = table->v;
- iter->end = iter->p + table->size;
-}
-
-static NAMED * FASTCALL
-hashTableIterNext(HASH_TABLE_ITER *iter)
-{
- while (iter->p != iter->end) {
- NAMED *tem = *(iter->p)++;
- if (tem)
- return tem;
- }
- return NULL;
-}
-
-static void FASTCALL
-poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
-{
- pool->blocks = NULL;
- pool->freeBlocks = NULL;
- pool->start = NULL;
- pool->ptr = NULL;
- pool->end = NULL;
- pool->mem = ms;
-}
-
-static void FASTCALL
-poolClear(STRING_POOL *pool)
-{
- if (!pool->freeBlocks)
- pool->freeBlocks = pool->blocks;
- else {
- BLOCK *p = pool->blocks;
- while (p) {
- BLOCK *tem = p->next;
- p->next = pool->freeBlocks;
- pool->freeBlocks = p;
- p = tem;
- }
- }
- pool->blocks = NULL;
- pool->start = NULL;
- pool->ptr = NULL;
- pool->end = NULL;
-}
-
-static void FASTCALL
-poolDestroy(STRING_POOL *pool)
-{
- BLOCK *p = pool->blocks;
- while (p) {
- BLOCK *tem = p->next;
- pool->mem->free_fcn(p);
- p = tem;
- }
- p = pool->freeBlocks;
- while (p) {
- BLOCK *tem = p->next;
- pool->mem->free_fcn(p);
- p = tem;
- }
-}
-
-static XML_Char *
-poolAppend(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end)
-{
- if (!pool->ptr && !poolGrow(pool))
- return NULL;
- for (;;) {
- const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
- if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
- break;
- if (!poolGrow(pool))
- return NULL;
- }
- return pool->start;
-}
-
-static const XML_Char * FASTCALL
-poolCopyString(STRING_POOL *pool, const XML_Char *s)
-{
- do {
- if (!poolAppendChar(pool, *s))
- return NULL;
- } while (*s++);
- s = pool->start;
- poolFinish(pool);
- return s;
-}
-
-static const XML_Char *
-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
-{
- if (!pool->ptr && !poolGrow(pool))
- return NULL;
- for (; n > 0; --n, s++) {
- if (!poolAppendChar(pool, *s))
- return NULL;
- }
- s = pool->start;
- poolFinish(pool);
- return s;
-}
-
-static const XML_Char * FASTCALL
-poolAppendString(STRING_POOL *pool, const XML_Char *s)
-{
- while (*s) {
- if (!poolAppendChar(pool, *s))
- return NULL;
- s++;
- }
- return pool->start;
-}
-
-static XML_Char *
-poolStoreString(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end)
-{
- if (!poolAppend(pool, enc, ptr, end))
- return NULL;
- if (pool->ptr == pool->end && !poolGrow(pool))
- return NULL;
- *(pool->ptr)++ = 0;
- return pool->start;
-}
-
-static XML_Bool FASTCALL
-poolGrow(STRING_POOL *pool)
-{
- if (pool->freeBlocks) {
- if (pool->start == 0) {
- pool->blocks = pool->freeBlocks;
- pool->freeBlocks = pool->freeBlocks->next;
- pool->blocks->next = NULL;
- pool->start = pool->blocks->s;
- pool->end = pool->start + pool->blocks->size;
- pool->ptr = pool->start;
- return XML_TRUE;
- }
- if (pool->end - pool->start < pool->freeBlocks->size) {
- BLOCK *tem = pool->freeBlocks->next;
- pool->freeBlocks->next = pool->blocks;
- pool->blocks = pool->freeBlocks;
- pool->freeBlocks = tem;
- memcpy(pool->blocks->s, pool->start,
- (pool->end - pool->start) * sizeof(XML_Char));
- pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
- pool->start = pool->blocks->s;
- pool->end = pool->start + pool->blocks->size;
- return XML_TRUE;
- }
- }
- if (pool->blocks && pool->start == pool->blocks->s) {
- BLOCK *temp;
- int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
-
- if (blockSize < 0)
- return XML_FALSE;
-
- temp = (BLOCK *)
- pool->mem->realloc_fcn(pool->blocks,
- (offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char)));
- if (temp == NULL)
- return XML_FALSE;
- pool->blocks = temp;
- pool->blocks->size = blockSize;
- pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
- pool->start = pool->blocks->s;
- pool->end = pool->start + blockSize;
- }
- else {
- BLOCK *tem;
- int blockSize = (int)(pool->end - pool->start);
-
- if (blockSize < 0)
- return XML_FALSE;
-
- if (blockSize < INIT_BLOCK_SIZE)
- blockSize = INIT_BLOCK_SIZE;
- else
- blockSize *= 2;
- tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char));
- if (!tem)
- return XML_FALSE;
- tem->size = blockSize;
- tem->next = pool->blocks;
- pool->blocks = tem;
- if (pool->ptr != pool->start)
- memcpy(tem->s, pool->start,
- (pool->ptr - pool->start) * sizeof(XML_Char));
- pool->ptr = tem->s + (pool->ptr - pool->start);
- pool->start = tem->s;
- pool->end = tem->s + blockSize;
- }
- return XML_TRUE;
-}
-
-static int FASTCALL
-nextScaffoldPart(XML_Parser parser)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
- CONTENT_SCAFFOLD * me;
- int next;
-
- if (!dtd->scaffIndex) {
- dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
- if (!dtd->scaffIndex)
- return -1;
- dtd->scaffIndex[0] = 0;
- }
-
- if (dtd->scaffCount >= dtd->scaffSize) {
- CONTENT_SCAFFOLD *temp;
- if (dtd->scaffold) {
- temp = (CONTENT_SCAFFOLD *)
- REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
- if (temp == NULL)
- return -1;
- dtd->scaffSize *= 2;
- }
- else {
- temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
- * sizeof(CONTENT_SCAFFOLD));
- if (temp == NULL)
- return -1;
- dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
- }
- dtd->scaffold = temp;
- }
- next = dtd->scaffCount++;
- me = &dtd->scaffold[next];
- if (dtd->scaffLevel) {
- CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
- if (parent->lastchild) {
- dtd->scaffold[parent->lastchild].nextsib = next;
- }
- if (!parent->childcnt)
- parent->firstchild = next;
- parent->lastchild = next;
- parent->childcnt++;
- }
- me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
- return next;
-}
-
-static void
-build_node(XML_Parser parser,
- int src_node,
- XML_Content *dest,
- XML_Content **contpos,
- XML_Char **strpos)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
- dest->type = dtd->scaffold[src_node].type;
- dest->quant = dtd->scaffold[src_node].quant;
- if (dest->type == XML_CTYPE_NAME) {
- const XML_Char *src;
- dest->name = *strpos;
- src = dtd->scaffold[src_node].name;
- for (;;) {
- *(*strpos)++ = *src;
- if (!*src)
- break;
- src++;
- }
- dest->numchildren = 0;
- dest->children = NULL;
- }
- else {
- unsigned int i;
- int cn;
- dest->numchildren = dtd->scaffold[src_node].childcnt;
- dest->children = *contpos;
- *contpos += dest->numchildren;
- for (i = 0, cn = dtd->scaffold[src_node].firstchild;
- i < dest->numchildren;
- i++, cn = dtd->scaffold[cn].nextsib) {
- build_node(parser, cn, &(dest->children[i]), contpos, strpos);
- }
- dest->name = NULL;
- }
-}
-
-static XML_Content *
-build_model (XML_Parser parser)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
- XML_Content *ret;
- XML_Content *cpos;
- XML_Char * str;
- int allocsize = (dtd->scaffCount * sizeof(XML_Content)
- + (dtd->contentStringLen * sizeof(XML_Char)));
-
- ret = (XML_Content *)MALLOC(allocsize);
- if (!ret)
- return NULL;
-
- str = (XML_Char *) (&ret[dtd->scaffCount]);
- cpos = &ret[1];
-
- build_node(parser, 0, ret, &cpos, &str);
- return ret;
-}
-
-static ELEMENT_TYPE *
-getElementType(XML_Parser parser,
- const ENCODING *enc,
- const char *ptr,
- const char *end)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
- const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
- ELEMENT_TYPE *ret;
-
- if (!name)
- return NULL;
- ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
- if (!ret)
- return NULL;
- if (ret->name != name)
- poolDiscard(&dtd->pool);
- else {
- poolFinish(&dtd->pool);
- if (!setElementTypePrefix(parser, ret))
- return NULL;
- }
- return ret;
-}
diff --git a/components/expat/library/xmlrole.c b/components/expat/library/xmlrole.c
deleted file mode 100644
index fcd0dc6948..0000000000
--- a/components/expat/library/xmlrole.c
+++ /dev/null
@@ -1,1336 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#include
-
-#ifdef WIN32
-#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
-#else
-#ifdef HAVE_EXPAT_CONFIG_H
-#include
-#endif
-#endif /* ndef WIN32 */
-
-#include "expat_external.h"
-#include "internal.h"
-#include "xmlrole.h"
-#include "ascii.h"
-
-/* Doesn't check:
-
- that ,| are not mixed in a model group
- content of literals
-
-*/
-
-static const char KW_ANY[] = {
- ASCII_A, ASCII_N, ASCII_Y, '\0' };
-static const char KW_ATTLIST[] = {
- ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
-static const char KW_CDATA[] = {
- ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_DOCTYPE[] = {
- ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
-static const char KW_ELEMENT[] = {
- ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
-static const char KW_EMPTY[] = {
- ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
-static const char KW_ENTITIES[] = {
- ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S,
- '\0' };
-static const char KW_ENTITY[] = {
- ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
-static const char KW_FIXED[] = {
- ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
-static const char KW_ID[] = {
- ASCII_I, ASCII_D, '\0' };
-static const char KW_IDREF[] = {
- ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
-static const char KW_IDREFS[] = {
- ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
-#ifdef XML_DTD
-static const char KW_IGNORE[] = {
- ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
-#endif
-static const char KW_IMPLIED[] = {
- ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
-#ifdef XML_DTD
-static const char KW_INCLUDE[] = {
- ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
-#endif
-static const char KW_NDATA[] = {
- ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_NMTOKEN[] = {
- ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
-static const char KW_NMTOKENS[] = {
- ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S,
- '\0' };
-static const char KW_NOTATION[] =
- { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N,
- '\0' };
-static const char KW_PCDATA[] = {
- ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_PUBLIC[] = {
- ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
-static const char KW_REQUIRED[] = {
- ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D,
- '\0' };
-static const char KW_SYSTEM[] = {
- ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
-
-#ifndef MIN_BYTES_PER_CHAR
-#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
-#endif
-
-#ifdef XML_DTD
-#define setTopLevel(state) \
- ((state)->handler = ((state)->documentEntity \
- ? internalSubset \
- : externalSubset1))
-#else /* not XML_DTD */
-#define setTopLevel(state) ((state)->handler = internalSubset)
-#endif /* not XML_DTD */
-
-typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc);
-
-static PROLOG_HANDLER
- prolog0, prolog1, prolog2,
- doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
- internalSubset,
- entity0, entity1, entity2, entity3, entity4, entity5, entity6,
- entity7, entity8, entity9, entity10,
- notation0, notation1, notation2, notation3, notation4,
- attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
- attlist7, attlist8, attlist9,
- element0, element1, element2, element3, element4, element5, element6,
- element7,
-#ifdef XML_DTD
- externalSubset0, externalSubset1,
- condSect0, condSect1, condSect2,
-#endif /* XML_DTD */
- declClose,
- error;
-
-static int FASTCALL common(PROLOG_STATE *state, int tok);
-
-static int PTRCALL
-prolog0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- state->handler = prolog1;
- return XML_ROLE_NONE;
- case XML_TOK_XML_DECL:
- state->handler = prolog1;
- return XML_ROLE_XML_DECL;
- case XML_TOK_PI:
- state->handler = prolog1;
- return XML_ROLE_PI;
- case XML_TOK_COMMENT:
- state->handler = prolog1;
- return XML_ROLE_COMMENT;
- case XML_TOK_BOM:
- return XML_ROLE_NONE;
- case XML_TOK_DECL_OPEN:
- if (!XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_DOCTYPE))
- break;
- state->handler = doctype0;
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_INSTANCE_START:
- state->handler = error;
- return XML_ROLE_INSTANCE_START;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-prolog1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_PI:
- return XML_ROLE_PI;
- case XML_TOK_COMMENT:
- return XML_ROLE_COMMENT;
- case XML_TOK_BOM:
- return XML_ROLE_NONE;
- case XML_TOK_DECL_OPEN:
- if (!XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_DOCTYPE))
- break;
- state->handler = doctype0;
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_INSTANCE_START:
- state->handler = error;
- return XML_ROLE_INSTANCE_START;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-prolog2(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_PI:
- return XML_ROLE_PI;
- case XML_TOK_COMMENT:
- return XML_ROLE_COMMENT;
- case XML_TOK_INSTANCE_START:
- state->handler = error;
- return XML_ROLE_INSTANCE_START;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-doctype0(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = doctype1;
- return XML_ROLE_DOCTYPE_NAME;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-doctype1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_OPEN_BRACKET:
- state->handler = internalSubset;
- return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
- case XML_TOK_DECL_CLOSE:
- state->handler = prolog2;
- return XML_ROLE_DOCTYPE_CLOSE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
- state->handler = doctype3;
- return XML_ROLE_DOCTYPE_NONE;
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
- state->handler = doctype2;
- return XML_ROLE_DOCTYPE_NONE;
- }
- break;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-doctype2(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_LITERAL:
- state->handler = doctype3;
- return XML_ROLE_DOCTYPE_PUBLIC_ID;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-doctype3(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_LITERAL:
- state->handler = doctype4;
- return XML_ROLE_DOCTYPE_SYSTEM_ID;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-doctype4(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_OPEN_BRACKET:
- state->handler = internalSubset;
- return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
- case XML_TOK_DECL_CLOSE:
- state->handler = prolog2;
- return XML_ROLE_DOCTYPE_CLOSE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-doctype5(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_DECL_CLOSE:
- state->handler = prolog2;
- return XML_ROLE_DOCTYPE_CLOSE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-internalSubset(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_DECL_OPEN:
- if (XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_ENTITY)) {
- state->handler = entity0;
- return XML_ROLE_ENTITY_NONE;
- }
- if (XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_ATTLIST)) {
- state->handler = attlist0;
- return XML_ROLE_ATTLIST_NONE;
- }
- if (XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_ELEMENT)) {
- state->handler = element0;
- return XML_ROLE_ELEMENT_NONE;
- }
- if (XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_NOTATION)) {
- state->handler = notation0;
- return XML_ROLE_NOTATION_NONE;
- }
- break;
- case XML_TOK_PI:
- return XML_ROLE_PI;
- case XML_TOK_COMMENT:
- return XML_ROLE_COMMENT;
- case XML_TOK_PARAM_ENTITY_REF:
- return XML_ROLE_PARAM_ENTITY_REF;
- case XML_TOK_CLOSE_BRACKET:
- state->handler = doctype5;
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_NONE:
- return XML_ROLE_NONE;
- }
- return common(state, tok);
-}
-
-#ifdef XML_DTD
-
-static int PTRCALL
-externalSubset0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- state->handler = externalSubset1;
- if (tok == XML_TOK_XML_DECL)
- return XML_ROLE_TEXT_DECL;
- return externalSubset1(state, tok, ptr, end, enc);
-}
-
-static int PTRCALL
-externalSubset1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_COND_SECT_OPEN:
- state->handler = condSect0;
- return XML_ROLE_NONE;
- case XML_TOK_COND_SECT_CLOSE:
- if (state->includeLevel == 0)
- break;
- state->includeLevel -= 1;
- return XML_ROLE_NONE;
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_CLOSE_BRACKET:
- break;
- case XML_TOK_NONE:
- if (state->includeLevel)
- break;
- return XML_ROLE_NONE;
- default:
- return internalSubset(state, tok, ptr, end, enc);
- }
- return common(state, tok);
-}
-
-#endif /* XML_DTD */
-
-static int PTRCALL
-entity0(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_PERCENT:
- state->handler = entity1;
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_NAME:
- state->handler = entity2;
- return XML_ROLE_GENERAL_ENTITY_NAME;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-entity1(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_NAME:
- state->handler = entity7;
- return XML_ROLE_PARAM_ENTITY_NAME;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-entity2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
- state->handler = entity4;
- return XML_ROLE_ENTITY_NONE;
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
- state->handler = entity3;
- return XML_ROLE_ENTITY_NONE;
- }
- break;
- case XML_TOK_LITERAL:
- state->handler = declClose;
- state->role_none = XML_ROLE_ENTITY_NONE;
- return XML_ROLE_ENTITY_VALUE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-entity3(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_LITERAL:
- state->handler = entity4;
- return XML_ROLE_ENTITY_PUBLIC_ID;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-entity4(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_LITERAL:
- state->handler = entity5;
- return XML_ROLE_ENTITY_SYSTEM_ID;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-entity5(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_DECL_CLOSE:
- setTopLevel(state);
- return XML_ROLE_ENTITY_COMPLETE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {
- state->handler = entity6;
- return XML_ROLE_ENTITY_NONE;
- }
- break;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-entity6(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_NAME:
- state->handler = declClose;
- state->role_none = XML_ROLE_ENTITY_NONE;
- return XML_ROLE_ENTITY_NOTATION_NAME;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-entity7(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
- state->handler = entity9;
- return XML_ROLE_ENTITY_NONE;
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
- state->handler = entity8;
- return XML_ROLE_ENTITY_NONE;
- }
- break;
- case XML_TOK_LITERAL:
- state->handler = declClose;
- state->role_none = XML_ROLE_ENTITY_NONE;
- return XML_ROLE_ENTITY_VALUE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-entity8(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_LITERAL:
- state->handler = entity9;
- return XML_ROLE_ENTITY_PUBLIC_ID;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-entity9(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_LITERAL:
- state->handler = entity10;
- return XML_ROLE_ENTITY_SYSTEM_ID;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-entity10(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_DECL_CLOSE:
- setTopLevel(state);
- return XML_ROLE_ENTITY_COMPLETE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-notation0(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NOTATION_NONE;
- case XML_TOK_NAME:
- state->handler = notation1;
- return XML_ROLE_NOTATION_NAME;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-notation1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NOTATION_NONE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
- state->handler = notation3;
- return XML_ROLE_NOTATION_NONE;
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
- state->handler = notation2;
- return XML_ROLE_NOTATION_NONE;
- }
- break;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-notation2(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NOTATION_NONE;
- case XML_TOK_LITERAL:
- state->handler = notation4;
- return XML_ROLE_NOTATION_PUBLIC_ID;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-notation3(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NOTATION_NONE;
- case XML_TOK_LITERAL:
- state->handler = declClose;
- state->role_none = XML_ROLE_NOTATION_NONE;
- return XML_ROLE_NOTATION_SYSTEM_ID;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-notation4(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NOTATION_NONE;
- case XML_TOK_LITERAL:
- state->handler = declClose;
- state->role_none = XML_ROLE_NOTATION_NONE;
- return XML_ROLE_NOTATION_SYSTEM_ID;
- case XML_TOK_DECL_CLOSE:
- setTopLevel(state);
- return XML_ROLE_NOTATION_NO_SYSTEM_ID;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-attlist0(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = attlist1;
- return XML_ROLE_ATTLIST_ELEMENT_NAME;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-attlist1(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_DECL_CLOSE:
- setTopLevel(state);
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = attlist2;
- return XML_ROLE_ATTRIBUTE_NAME;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-attlist2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_NAME:
- {
- static const char * const types[] = {
- KW_CDATA,
- KW_ID,
- KW_IDREF,
- KW_IDREFS,
- KW_ENTITY,
- KW_ENTITIES,
- KW_NMTOKEN,
- KW_NMTOKENS,
- };
- int i;
- for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
- if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
- state->handler = attlist8;
- return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
- }
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
- state->handler = attlist5;
- return XML_ROLE_ATTLIST_NONE;
- }
- break;
- case XML_TOK_OPEN_PAREN:
- state->handler = attlist3;
- return XML_ROLE_ATTLIST_NONE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-attlist3(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_NMTOKEN:
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = attlist4;
- return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-attlist4(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_CLOSE_PAREN:
- state->handler = attlist8;
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_OR:
- state->handler = attlist3;
- return XML_ROLE_ATTLIST_NONE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-attlist5(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_OPEN_PAREN:
- state->handler = attlist6;
- return XML_ROLE_ATTLIST_NONE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-attlist6(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_NAME:
- state->handler = attlist7;
- return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-attlist7(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_CLOSE_PAREN:
- state->handler = attlist8;
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_OR:
- state->handler = attlist6;
- return XML_ROLE_ATTLIST_NONE;
- }
- return common(state, tok);
-}
-
-/* default value */
-static int PTRCALL
-attlist8(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_POUND_NAME:
- if (XmlNameMatchesAscii(enc,
- ptr + MIN_BYTES_PER_CHAR(enc),
- end,
- KW_IMPLIED)) {
- state->handler = attlist1;
- return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
- }
- if (XmlNameMatchesAscii(enc,
- ptr + MIN_BYTES_PER_CHAR(enc),
- end,
- KW_REQUIRED)) {
- state->handler = attlist1;
- return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
- }
- if (XmlNameMatchesAscii(enc,
- ptr + MIN_BYTES_PER_CHAR(enc),
- end,
- KW_FIXED)) {
- state->handler = attlist9;
- return XML_ROLE_ATTLIST_NONE;
- }
- break;
- case XML_TOK_LITERAL:
- state->handler = attlist1;
- return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-attlist9(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_LITERAL:
- state->handler = attlist1;
- return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-element0(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = element1;
- return XML_ROLE_ELEMENT_NAME;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-element1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- return XML_ROLE_CONTENT_EMPTY;
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- return XML_ROLE_CONTENT_ANY;
- }
- break;
- case XML_TOK_OPEN_PAREN:
- state->handler = element2;
- state->level = 1;
- return XML_ROLE_GROUP_OPEN;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-element2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_POUND_NAME:
- if (XmlNameMatchesAscii(enc,
- ptr + MIN_BYTES_PER_CHAR(enc),
- end,
- KW_PCDATA)) {
- state->handler = element3;
- return XML_ROLE_CONTENT_PCDATA;
- }
- break;
- case XML_TOK_OPEN_PAREN:
- state->level = 2;
- state->handler = element6;
- return XML_ROLE_GROUP_OPEN;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT;
- case XML_TOK_NAME_QUESTION:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT_OPT;
- case XML_TOK_NAME_ASTERISK:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT_REP;
- case XML_TOK_NAME_PLUS:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT_PLUS;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-element3(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_CLOSE_PAREN:
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- return XML_ROLE_GROUP_CLOSE;
- case XML_TOK_CLOSE_PAREN_ASTERISK:
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- return XML_ROLE_GROUP_CLOSE_REP;
- case XML_TOK_OR:
- state->handler = element4;
- return XML_ROLE_ELEMENT_NONE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-element4(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = element5;
- return XML_ROLE_CONTENT_ELEMENT;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-element5(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_CLOSE_PAREN_ASTERISK:
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- return XML_ROLE_GROUP_CLOSE_REP;
- case XML_TOK_OR:
- state->handler = element4;
- return XML_ROLE_ELEMENT_NONE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-element6(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_OPEN_PAREN:
- state->level += 1;
- return XML_ROLE_GROUP_OPEN;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT;
- case XML_TOK_NAME_QUESTION:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT_OPT;
- case XML_TOK_NAME_ASTERISK:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT_REP;
- case XML_TOK_NAME_PLUS:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT_PLUS;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-element7(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_CLOSE_PAREN:
- state->level -= 1;
- if (state->level == 0) {
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- }
- return XML_ROLE_GROUP_CLOSE;
- case XML_TOK_CLOSE_PAREN_ASTERISK:
- state->level -= 1;
- if (state->level == 0) {
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- }
- return XML_ROLE_GROUP_CLOSE_REP;
- case XML_TOK_CLOSE_PAREN_QUESTION:
- state->level -= 1;
- if (state->level == 0) {
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- }
- return XML_ROLE_GROUP_CLOSE_OPT;
- case XML_TOK_CLOSE_PAREN_PLUS:
- state->level -= 1;
- if (state->level == 0) {
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- }
- return XML_ROLE_GROUP_CLOSE_PLUS;
- case XML_TOK_COMMA:
- state->handler = element6;
- return XML_ROLE_GROUP_SEQUENCE;
- case XML_TOK_OR:
- state->handler = element6;
- return XML_ROLE_GROUP_CHOICE;
- }
- return common(state, tok);
-}
-
-#ifdef XML_DTD
-
-static int PTRCALL
-condSect0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) {
- state->handler = condSect1;
- return XML_ROLE_NONE;
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) {
- state->handler = condSect2;
- return XML_ROLE_NONE;
- }
- break;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-condSect1(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_OPEN_BRACKET:
- state->handler = externalSubset1;
- state->includeLevel += 1;
- return XML_ROLE_NONE;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-condSect2(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_OPEN_BRACKET:
- state->handler = externalSubset1;
- return XML_ROLE_IGNORE_SECT;
- }
- return common(state, tok);
-}
-
-#endif /* XML_DTD */
-
-static int PTRCALL
-declClose(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return state->role_none;
- case XML_TOK_DECL_CLOSE:
- setTopLevel(state);
- return state->role_none;
- }
- return common(state, tok);
-}
-
-static int PTRCALL
-error(PROLOG_STATE *UNUSED_P(state),
- int UNUSED_P(tok),
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
- return XML_ROLE_NONE;
-}
-
-static int FASTCALL
-common(PROLOG_STATE *state, int tok)
-{
-#ifdef XML_DTD
- if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
- return XML_ROLE_INNER_PARAM_ENTITY_REF;
-#endif
- state->handler = error;
- return XML_ROLE_ERROR;
-}
-
-void
-XmlPrologStateInit(PROLOG_STATE *state)
-{
- state->handler = prolog0;
-#ifdef XML_DTD
- state->documentEntity = 1;
- state->includeLevel = 0;
- state->inEntityValue = 0;
-#endif /* XML_DTD */
-}
-
-#ifdef XML_DTD
-
-void
-XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
-{
- state->handler = externalSubset0;
- state->documentEntity = 0;
- state->includeLevel = 0;
-}
-
-#endif /* XML_DTD */
diff --git a/components/expat/library/xmltok.c b/components/expat/library/xmltok.c
deleted file mode 100644
index b014e72ce1..0000000000
--- a/components/expat/library/xmltok.c
+++ /dev/null
@@ -1,1753 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#include
-
-#ifdef WIN32
-#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
-#else
-#ifdef HAVE_EXPAT_CONFIG_H
-#include
-#endif
-#endif /* ndef WIN32 */
-
-#include "expat_external.h"
-#include "internal.h"
-#include "xmltok.h"
-#include "nametab.h"
-
-#ifdef XML_DTD
-#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
-#else
-#define IGNORE_SECTION_TOK_VTABLE /* as nothing */
-#endif
-
-#define VTABLE1 \
- { PREFIX(prologTok), PREFIX(contentTok), \
- PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
- { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
- PREFIX(sameName), \
- PREFIX(nameMatchesAscii), \
- PREFIX(nameLength), \
- PREFIX(skipS), \
- PREFIX(getAtts), \
- PREFIX(charRefNumber), \
- PREFIX(predefinedEntityName), \
- PREFIX(updatePosition), \
- PREFIX(isPublicId)
-
-#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
-
-#define UCS2_GET_NAMING(pages, hi, lo) \
- (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F)))
-
-/* A 2 byte UTF-8 representation splits the characters 11 bits between
- the bottom 5 and 6 bits of the bytes. We need 8 bits to index into
- pages, 3 bits to add to that index and 5 bits to generate the mask.
-*/
-#define UTF8_GET_NAMING2(pages, byte) \
- (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
- + ((((byte)[0]) & 3) << 1) \
- + ((((byte)[1]) >> 5) & 1)] \
- & (1u << (((byte)[1]) & 0x1F)))
-
-/* A 3 byte UTF-8 representation splits the characters 16 bits between
- the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index
- into pages, 3 bits to add to that index and 5 bits to generate the
- mask.
-*/
-#define UTF8_GET_NAMING3(pages, byte) \
- (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
- + ((((byte)[1]) >> 2) & 0xF)] \
- << 3) \
- + ((((byte)[1]) & 3) << 1) \
- + ((((byte)[2]) >> 5) & 1)] \
- & (1u << (((byte)[2]) & 0x1F)))
-
-#define UTF8_GET_NAMING(pages, p, n) \
- ((n) == 2 \
- ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
- : ((n) == 3 \
- ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
- : 0))
-
-/* Detection of invalid UTF-8 sequences is based on Table 3.1B
- of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/
- with the additional restriction of not allowing the Unicode
- code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE).
- Implementation details:
- (A & 0x80) == 0 means A < 0x80
- and
- (A & 0xC0) == 0xC0 means A > 0xBF
-*/
-
-#define UTF8_INVALID2(p) \
- ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
-
-#define UTF8_INVALID3(p) \
- (((p)[2] & 0x80) == 0 \
- || \
- ((*p) == 0xEF && (p)[1] == 0xBF \
- ? \
- (p)[2] > 0xBD \
- : \
- ((p)[2] & 0xC0) == 0xC0) \
- || \
- ((*p) == 0xE0 \
- ? \
- (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \
- : \
- ((p)[1] & 0x80) == 0 \
- || \
- ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
-
-#define UTF8_INVALID4(p) \
- (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \
- || \
- ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \
- || \
- ((*p) == 0xF0 \
- ? \
- (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
- : \
- ((p)[1] & 0x80) == 0 \
- || \
- ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
-
-static int PTRFASTCALL
-isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p))
-{
- return 0;
-}
-
-static int PTRFASTCALL
-utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p)
-{
- return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
-}
-
-static int PTRFASTCALL
-utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p)
-{
- return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
-}
-
-#define utf8_isName4 isNever
-
-static int PTRFASTCALL
-utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p)
-{
- return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
-}
-
-static int PTRFASTCALL
-utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p)
-{
- return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
-}
-
-#define utf8_isNmstrt4 isNever
-
-static int PTRFASTCALL
-utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p)
-{
- return UTF8_INVALID2((const unsigned char *)p);
-}
-
-static int PTRFASTCALL
-utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p)
-{
- return UTF8_INVALID3((const unsigned char *)p);
-}
-
-static int PTRFASTCALL
-utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p)
-{
- return UTF8_INVALID4((const unsigned char *)p);
-}
-
-struct normal_encoding {
- ENCODING enc;
- unsigned char type[256];
-#ifdef XML_MIN_SIZE
- int (PTRFASTCALL *byteType)(const ENCODING *, const char *);
- int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
- int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
- int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
- int (PTRCALL *charMatches)(const ENCODING *, const char *, int);
-#endif /* XML_MIN_SIZE */
- int (PTRFASTCALL *isName2)(const ENCODING *, const char *);
- int (PTRFASTCALL *isName3)(const ENCODING *, const char *);
- int (PTRFASTCALL *isName4)(const ENCODING *, const char *);
- int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
- int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
- int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
- int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
- int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
- int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
-};
-
-#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *) (enc))
-
-#ifdef XML_MIN_SIZE
-
-#define STANDARD_VTABLE(E) \
- E ## byteType, \
- E ## isNameMin, \
- E ## isNmstrtMin, \
- E ## byteToAscii, \
- E ## charMatches,
-
-#else
-
-#define STANDARD_VTABLE(E) /* as nothing */
-
-#endif
-
-#define NORMAL_VTABLE(E) \
- E ## isName2, \
- E ## isName3, \
- E ## isName4, \
- E ## isNmstrt2, \
- E ## isNmstrt3, \
- E ## isNmstrt4, \
- E ## isInvalid2, \
- E ## isInvalid3, \
- E ## isInvalid4
-
-#define NULL_VTABLE \
- /* isName2 */ NULL, \
- /* isName3 */ NULL, \
- /* isName4 */ NULL, \
- /* isNmstrt2 */ NULL, \
- /* isNmstrt3 */ NULL, \
- /* isNmstrt4 */ NULL, \
- /* isInvalid2 */ NULL, \
- /* isInvalid3 */ NULL, \
- /* isInvalid4 */ NULL
-
-static int FASTCALL checkCharRefNumber(int);
-
-#include "xmltok_impl.h"
-#include "ascii.h"
-
-#ifdef XML_MIN_SIZE
-#define sb_isNameMin isNever
-#define sb_isNmstrtMin isNever
-#endif
-
-#ifdef XML_MIN_SIZE
-#define MINBPC(enc) ((enc)->minBytesPerChar)
-#else
-/* minimum bytes per character */
-#define MINBPC(enc) 1
-#endif
-
-#define SB_BYTE_TYPE(enc, p) \
- (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
-
-#ifdef XML_MIN_SIZE
-static int PTRFASTCALL
-sb_byteType(const ENCODING *enc, const char *p)
-{
- return SB_BYTE_TYPE(enc, p);
-}
-#define BYTE_TYPE(enc, p) \
- (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
-#else
-#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
-#endif
-
-#ifdef XML_MIN_SIZE
-#define BYTE_TO_ASCII(enc, p) \
- (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
-static int PTRFASTCALL
-sb_byteToAscii(const ENCODING *enc, const char *p)
-{
- return *p;
-}
-#else
-#define BYTE_TO_ASCII(enc, p) (*(p))
-#endif
-
-#define IS_NAME_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p))
-#define IS_NMSTRT_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p))
-#define IS_INVALID_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p))
-
-#ifdef XML_MIN_SIZE
-#define IS_NAME_CHAR_MINBPC(enc, p) \
- (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
- (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
-#else
-#define IS_NAME_CHAR_MINBPC(enc, p) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
-#endif
-
-#ifdef XML_MIN_SIZE
-#define CHAR_MATCHES(enc, p, c) \
- (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
-static int PTRCALL
-sb_charMatches(const ENCODING *enc, const char *p, int c)
-{
- return *p == c;
-}
-#else
-/* c is an ASCII character */
-#define CHAR_MATCHES(enc, p, c) (*(p) == c)
-#endif
-
-#define PREFIX(ident) normal_ ## ident
-#define XML_TOK_IMPL_C
-#include "xmltok_impl.c"
-#undef XML_TOK_IMPL_C
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
-
-enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */
- UTF8_cval1 = 0x00,
- UTF8_cval2 = 0xc0,
- UTF8_cval3 = 0xe0,
- UTF8_cval4 = 0xf0
-};
-
-void
-align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef)
-{
- const char * fromLim = *fromLimRef;
- size_t walked = 0;
- for (; fromLim > from; fromLim--, walked++) {
- const unsigned char prev = (unsigned char)fromLim[-1];
- if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */
- if (walked + 1 >= 4) {
- fromLim += 4 - 1;
- break;
- } else {
- walked = 0;
- }
- } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */
- if (walked + 1 >= 3) {
- fromLim += 3 - 1;
- break;
- } else {
- walked = 0;
- }
- } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */
- if (walked + 1 >= 2) {
- fromLim += 2 - 1;
- break;
- } else {
- walked = 0;
- }
- } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */
- break;
- }
- }
- *fromLimRef = fromLim;
-}
-
-static enum XML_Convert_Result PTRCALL
-utf8_toUtf8(const ENCODING *UNUSED_P(enc),
- const char **fromP, const char *fromLim,
- char **toP, const char *toLim)
-{
- enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
- char *to;
- const char *from;
- if (fromLim - *fromP > toLim - *toP) {
- /* Avoid copying partial characters. */
- res = XML_CONVERT_OUTPUT_EXHAUSTED;
- fromLim = *fromP + (toLim - *toP);
- align_limit_to_full_utf8_characters(*fromP, &fromLim);
- }
- for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++)
- *to = *from;
- *fromP = from;
- *toP = to;
-
- if ((to == toLim) && (from < fromLim))
- return XML_CONVERT_OUTPUT_EXHAUSTED;
- else
- return res;
-}
-
-static enum XML_Convert_Result PTRCALL
-utf8_toUtf16(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- unsigned short **toP, const unsigned short *toLim)
-{
- enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
- unsigned short *to = *toP;
- const char *from = *fromP;
- while (from < fromLim && to < toLim) {
- switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
- case BT_LEAD2:
- if (fromLim - from < 2) {
- res = XML_CONVERT_INPUT_INCOMPLETE;
- goto after;
- }
- *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
- from += 2;
- break;
- case BT_LEAD3:
- if (fromLim - from < 3) {
- res = XML_CONVERT_INPUT_INCOMPLETE;
- goto after;
- }
- *to++ = (unsigned short)(((from[0] & 0xf) << 12)
- | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
- from += 3;
- break;
- case BT_LEAD4:
- {
- unsigned long n;
- if (toLim - to < 2) {
- res = XML_CONVERT_OUTPUT_EXHAUSTED;
- goto after;
- }
- if (fromLim - from < 4) {
- res = XML_CONVERT_INPUT_INCOMPLETE;
- goto after;
- }
- n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
- | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
- n -= 0x10000;
- to[0] = (unsigned short)((n >> 10) | 0xD800);
- to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
- to += 2;
- from += 4;
- }
- break;
- default:
- *to++ = *from++;
- break;
- }
- }
- if (from < fromLim)
- res = XML_CONVERT_OUTPUT_EXHAUSTED;
-after:
- *fromP = from;
- *toP = to;
- return res;
-}
-
-#ifdef XML_NS
-static const struct normal_encoding utf8_encoding_ns = {
- { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
- {
-#include "asciitab.h"
-#include "utf8tab.h"
- },
- STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
-#endif
-
-static const struct normal_encoding utf8_encoding = {
- { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
- {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "utf8tab.h"
- },
- STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
-
-#ifdef XML_NS
-
-static const struct normal_encoding internal_utf8_encoding_ns = {
- { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
- {
-#include "iasciitab.h"
-#include "utf8tab.h"
- },
- STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
-
-#endif
-
-static const struct normal_encoding internal_utf8_encoding = {
- { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
- {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "utf8tab.h"
- },
- STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
-
-static enum XML_Convert_Result PTRCALL
-latin1_toUtf8(const ENCODING *UNUSED_P(enc),
- const char **fromP, const char *fromLim,
- char **toP, const char *toLim)
-{
- for (;;) {
- unsigned char c;
- if (*fromP == fromLim)
- return XML_CONVERT_COMPLETED;
- c = (unsigned char)**fromP;
- if (c & 0x80) {
- if (toLim - *toP < 2)
- return XML_CONVERT_OUTPUT_EXHAUSTED;
- *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
- *(*toP)++ = (char)((c & 0x3f) | 0x80);
- (*fromP)++;
- }
- else {
- if (*toP == toLim)
- return XML_CONVERT_OUTPUT_EXHAUSTED;
- *(*toP)++ = *(*fromP)++;
- }
- }
-}
-
-static enum XML_Convert_Result PTRCALL
-latin1_toUtf16(const ENCODING *UNUSED_P(enc),
- const char **fromP, const char *fromLim,
- unsigned short **toP, const unsigned short *toLim)
-{
- while (*fromP < fromLim && *toP < toLim)
- *(*toP)++ = (unsigned char)*(*fromP)++;
-
- if ((*toP == toLim) && (*fromP < fromLim))
- return XML_CONVERT_OUTPUT_EXHAUSTED;
- else
- return XML_CONVERT_COMPLETED;
-}
-
-#ifdef XML_NS
-
-static const struct normal_encoding latin1_encoding_ns = {
- { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
- {
-#include "asciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(sb_) NULL_VTABLE
-};
-
-#endif
-
-static const struct normal_encoding latin1_encoding = {
- { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
- {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(sb_) NULL_VTABLE
-};
-
-static enum XML_Convert_Result PTRCALL
-ascii_toUtf8(const ENCODING *UNUSED_P(enc),
- const char **fromP, const char *fromLim,
- char **toP, const char *toLim)
-{
- while (*fromP < fromLim && *toP < toLim)
- *(*toP)++ = *(*fromP)++;
-
- if ((*toP == toLim) && (*fromP < fromLim))
- return XML_CONVERT_OUTPUT_EXHAUSTED;
- else
- return XML_CONVERT_COMPLETED;
-}
-
-#ifdef XML_NS
-
-static const struct normal_encoding ascii_encoding_ns = {
- { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
- {
-#include "asciitab.h"
-/* BT_NONXML == 0 */
- },
- STANDARD_VTABLE(sb_) NULL_VTABLE
-};
-
-#endif
-
-static const struct normal_encoding ascii_encoding = {
- { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
- {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-/* BT_NONXML == 0 */
- },
- STANDARD_VTABLE(sb_) NULL_VTABLE
-};
-
-static int PTRFASTCALL
-unicode_byte_type(char hi, char lo)
-{
- switch ((unsigned char)hi) {
- case 0xD8: case 0xD9: case 0xDA: case 0xDB:
- return BT_LEAD4;
- case 0xDC: case 0xDD: case 0xDE: case 0xDF:
- return BT_TRAIL;
- case 0xFF:
- switch ((unsigned char)lo) {
- case 0xFF:
- case 0xFE:
- return BT_NONXML;
- }
- break;
- }
- return BT_NONASCII;
-}
-
-#define DEFINE_UTF16_TO_UTF8(E) \
-static enum XML_Convert_Result PTRCALL \
-E ## toUtf8(const ENCODING *UNUSED_P(enc), \
- const char **fromP, const char *fromLim, \
- char **toP, const char *toLim) \
-{ \
- const char *from = *fromP; \
- fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \
- for (; from < fromLim; from += 2) { \
- int plane; \
- unsigned char lo2; \
- unsigned char lo = GET_LO(from); \
- unsigned char hi = GET_HI(from); \
- switch (hi) { \
- case 0: \
- if (lo < 0x80) { \
- if (*toP == toLim) { \
- *fromP = from; \
- return XML_CONVERT_OUTPUT_EXHAUSTED; \
- } \
- *(*toP)++ = lo; \
- break; \
- } \
- /* fall through */ \
- case 0x1: case 0x2: case 0x3: \
- case 0x4: case 0x5: case 0x6: case 0x7: \
- if (toLim - *toP < 2) { \
- *fromP = from; \
- return XML_CONVERT_OUTPUT_EXHAUSTED; \
- } \
- *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \
- *(*toP)++ = ((lo & 0x3f) | 0x80); \
- break; \
- default: \
- if (toLim - *toP < 3) { \
- *fromP = from; \
- return XML_CONVERT_OUTPUT_EXHAUSTED; \
- } \
- /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
- *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
- *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
- *(*toP)++ = ((lo & 0x3f) | 0x80); \
- break; \
- case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
- if (toLim - *toP < 4) { \
- *fromP = from; \
- return XML_CONVERT_OUTPUT_EXHAUSTED; \
- } \
- if (fromLim - from < 4) { \
- *fromP = from; \
- return XML_CONVERT_INPUT_INCOMPLETE; \
- } \
- plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
- *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
- *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
- from += 2; \
- lo2 = GET_LO(from); \
- *(*toP)++ = (((lo & 0x3) << 4) \
- | ((GET_HI(from) & 0x3) << 2) \
- | (lo2 >> 6) \
- | 0x80); \
- *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
- break; \
- } \
- } \
- *fromP = from; \
- if (from < fromLim) \
- return XML_CONVERT_INPUT_INCOMPLETE; \
- else \
- return XML_CONVERT_COMPLETED; \
-}
-
-#define DEFINE_UTF16_TO_UTF16(E) \
-static enum XML_Convert_Result PTRCALL \
-E ## toUtf16(const ENCODING *UNUSED_P(enc), \
- const char **fromP, const char *fromLim, \
- unsigned short **toP, const unsigned short *toLim) \
-{ \
- enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
- fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \
- /* Avoid copying first half only of surrogate */ \
- if (fromLim - *fromP > ((toLim - *toP) << 1) \
- && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
- fromLim -= 2; \
- res = XML_CONVERT_INPUT_INCOMPLETE; \
- } \
- for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \
- *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
- if ((*toP == toLim) && (*fromP < fromLim)) \
- return XML_CONVERT_OUTPUT_EXHAUSTED; \
- else \
- return res; \
-}
-
-#define SET2(ptr, ch) \
- (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
-#define GET_LO(ptr) ((unsigned char)(ptr)[0])
-#define GET_HI(ptr) ((unsigned char)(ptr)[1])
-
-DEFINE_UTF16_TO_UTF8(little2_)
-DEFINE_UTF16_TO_UTF16(little2_)
-
-#undef SET2
-#undef GET_LO
-#undef GET_HI
-
-#define SET2(ptr, ch) \
- (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
-#define GET_LO(ptr) ((unsigned char)(ptr)[1])
-#define GET_HI(ptr) ((unsigned char)(ptr)[0])
-
-DEFINE_UTF16_TO_UTF8(big2_)
-DEFINE_UTF16_TO_UTF16(big2_)
-
-#undef SET2
-#undef GET_LO
-#undef GET_HI
-
-#define LITTLE2_BYTE_TYPE(enc, p) \
- ((p)[1] == 0 \
- ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
- : unicode_byte_type((p)[1], (p)[0]))
-#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
-#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
-#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
- UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
-#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
- UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
-
-#ifdef XML_MIN_SIZE
-
-static int PTRFASTCALL
-little2_byteType(const ENCODING *enc, const char *p)
-{
- return LITTLE2_BYTE_TYPE(enc, p);
-}
-
-static int PTRFASTCALL
-little2_byteToAscii(const ENCODING *enc, const char *p)
-{
- return LITTLE2_BYTE_TO_ASCII(enc, p);
-}
-
-static int PTRCALL
-little2_charMatches(const ENCODING *enc, const char *p, int c)
-{
- return LITTLE2_CHAR_MATCHES(enc, p, c);
-}
-
-static int PTRFASTCALL
-little2_isNameMin(const ENCODING *enc, const char *p)
-{
- return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
-}
-
-static int PTRFASTCALL
-little2_isNmstrtMin(const ENCODING *enc, const char *p)
-{
- return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
-}
-
-#undef VTABLE
-#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
-
-#else /* not XML_MIN_SIZE */
-
-#undef PREFIX
-#define PREFIX(ident) little2_ ## ident
-#define MINBPC(enc) 2
-/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
-#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p)
-#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
-#define IS_NAME_CHAR(enc, p, n) 0
-#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
-#define IS_NMSTRT_CHAR(enc, p, n) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
-
-#define XML_TOK_IMPL_C
-#include "xmltok_impl.c"
-#undef XML_TOK_IMPL_C
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
-
-#endif /* not XML_MIN_SIZE */
-
-#ifdef XML_NS
-
-static const struct normal_encoding little2_encoding_ns = {
- { VTABLE, 2, 0,
-#if BYTEORDER == 1234
- 1
-#else
- 0
-#endif
- },
- {
-#include "asciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(little2_) NULL_VTABLE
-};
-
-#endif
-
-static const struct normal_encoding little2_encoding = {
- { VTABLE, 2, 0,
-#if BYTEORDER == 1234
- 1
-#else
- 0
-#endif
- },
- {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(little2_) NULL_VTABLE
-};
-
-#if BYTEORDER != 4321
-
-#ifdef XML_NS
-
-static const struct normal_encoding internal_little2_encoding_ns = {
- { VTABLE, 2, 0, 1 },
- {
-#include "iasciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(little2_) NULL_VTABLE
-};
-
-#endif
-
-static const struct normal_encoding internal_little2_encoding = {
- { VTABLE, 2, 0, 1 },
- {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(little2_) NULL_VTABLE
-};
-
-#endif
-
-
-#define BIG2_BYTE_TYPE(enc, p) \
- ((p)[0] == 0 \
- ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
- : unicode_byte_type((p)[0], (p)[1]))
-#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
-#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
-#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
- UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
-#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
- UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
-
-#ifdef XML_MIN_SIZE
-
-static int PTRFASTCALL
-big2_byteType(const ENCODING *enc, const char *p)
-{
- return BIG2_BYTE_TYPE(enc, p);
-}
-
-static int PTRFASTCALL
-big2_byteToAscii(const ENCODING *enc, const char *p)
-{
- return BIG2_BYTE_TO_ASCII(enc, p);
-}
-
-static int PTRCALL
-big2_charMatches(const ENCODING *enc, const char *p, int c)
-{
- return BIG2_CHAR_MATCHES(enc, p, c);
-}
-
-static int PTRFASTCALL
-big2_isNameMin(const ENCODING *enc, const char *p)
-{
- return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
-}
-
-static int PTRFASTCALL
-big2_isNmstrtMin(const ENCODING *enc, const char *p)
-{
- return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
-}
-
-#undef VTABLE
-#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
-
-#else /* not XML_MIN_SIZE */
-
-#undef PREFIX
-#define PREFIX(ident) big2_ ## ident
-#define MINBPC(enc) 2
-/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
-#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p)
-#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
-#define IS_NAME_CHAR(enc, p, n) 0
-#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
-#define IS_NMSTRT_CHAR(enc, p, n) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
-
-#define XML_TOK_IMPL_C
-#include "xmltok_impl.c"
-#undef XML_TOK_IMPL_C
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
-
-#endif /* not XML_MIN_SIZE */
-
-#ifdef XML_NS
-
-static const struct normal_encoding big2_encoding_ns = {
- { VTABLE, 2, 0,
-#if BYTEORDER == 4321
- 1
-#else
- 0
-#endif
- },
- {
-#include "asciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(big2_) NULL_VTABLE
-};
-
-#endif
-
-static const struct normal_encoding big2_encoding = {
- { VTABLE, 2, 0,
-#if BYTEORDER == 4321
- 1
-#else
- 0
-#endif
- },
- {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(big2_) NULL_VTABLE
-};
-
-#if BYTEORDER != 1234
-
-#ifdef XML_NS
-
-static const struct normal_encoding internal_big2_encoding_ns = {
- { VTABLE, 2, 0, 1 },
- {
-#include "iasciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(big2_) NULL_VTABLE
-};
-
-#endif
-
-static const struct normal_encoding internal_big2_encoding = {
- { VTABLE, 2, 0, 1 },
- {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(big2_) NULL_VTABLE
-};
-
-#endif
-
-#undef PREFIX
-
-static int FASTCALL
-streqci(const char *s1, const char *s2)
-{
- for (;;) {
- char c1 = *s1++;
- char c2 = *s2++;
- if (ASCII_a <= c1 && c1 <= ASCII_z)
- c1 += ASCII_A - ASCII_a;
- if (ASCII_a <= c2 && c2 <= ASCII_z)
- c2 += ASCII_A - ASCII_a;
- if (c1 != c2)
- return 0;
- if (!c1)
- break;
- }
- return 1;
-}
-
-static void PTRCALL
-initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr,
- const char *end, POSITION *pos)
-{
- normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
-}
-
-static int
-toAscii(const ENCODING *enc, const char *ptr, const char *end)
-{
- char buf[1];
- char *p = buf;
- XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
- if (p == buf)
- return -1;
- else
- return buf[0];
-}
-
-static int FASTCALL
-isSpace(int c)
-{
- switch (c) {
- case 0x20:
- case 0xD:
- case 0xA:
- case 0x9:
- return 1;
- }
- return 0;
-}
-
-/* Return 1 if there's just optional white space or there's an S
- followed by name=val.
-*/
-static int
-parsePseudoAttribute(const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **namePtr,
- const char **nameEndPtr,
- const char **valPtr,
- const char **nextTokPtr)
-{
- int c;
- char open;
- if (ptr == end) {
- *namePtr = NULL;
- return 1;
- }
- if (!isSpace(toAscii(enc, ptr, end))) {
- *nextTokPtr = ptr;
- return 0;
- }
- do {
- ptr += enc->minBytesPerChar;
- } while (isSpace(toAscii(enc, ptr, end)));
- if (ptr == end) {
- *namePtr = NULL;
- return 1;
- }
- *namePtr = ptr;
- for (;;) {
- c = toAscii(enc, ptr, end);
- if (c == -1) {
- *nextTokPtr = ptr;
- return 0;
- }
- if (c == ASCII_EQUALS) {
- *nameEndPtr = ptr;
- break;
- }
- if (isSpace(c)) {
- *nameEndPtr = ptr;
- do {
- ptr += enc->minBytesPerChar;
- } while (isSpace(c = toAscii(enc, ptr, end)));
- if (c != ASCII_EQUALS) {
- *nextTokPtr = ptr;
- return 0;
- }
- break;
- }
- ptr += enc->minBytesPerChar;
- }
- if (ptr == *namePtr) {
- *nextTokPtr = ptr;
- return 0;
- }
- ptr += enc->minBytesPerChar;
- c = toAscii(enc, ptr, end);
- while (isSpace(c)) {
- ptr += enc->minBytesPerChar;
- c = toAscii(enc, ptr, end);
- }
- if (c != ASCII_QUOT && c != ASCII_APOS) {
- *nextTokPtr = ptr;
- return 0;
- }
- open = (char)c;
- ptr += enc->minBytesPerChar;
- *valPtr = ptr;
- for (;; ptr += enc->minBytesPerChar) {
- c = toAscii(enc, ptr, end);
- if (c == open)
- break;
- if (!(ASCII_a <= c && c <= ASCII_z)
- && !(ASCII_A <= c && c <= ASCII_Z)
- && !(ASCII_0 <= c && c <= ASCII_9)
- && c != ASCII_PERIOD
- && c != ASCII_MINUS
- && c != ASCII_UNDERSCORE) {
- *nextTokPtr = ptr;
- return 0;
- }
- }
- *nextTokPtr = ptr + enc->minBytesPerChar;
- return 1;
-}
-
-static const char KW_version[] = {
- ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'
-};
-
-static const char KW_encoding[] = {
- ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'
-};
-
-static const char KW_standalone[] = {
- ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o,
- ASCII_n, ASCII_e, '\0'
-};
-
-static const char KW_yes[] = {
- ASCII_y, ASCII_e, ASCII_s, '\0'
-};
-
-static const char KW_no[] = {
- ASCII_n, ASCII_o, '\0'
-};
-
-static int
-doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
- const char *,
- const char *),
- int isGeneralTextEntity,
- const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr,
- const char **versionPtr,
- const char **versionEndPtr,
- const char **encodingName,
- const ENCODING **encoding,
- int *standalone)
-{
- const char *val = NULL;
- const char *name = NULL;
- const char *nameEnd = NULL;
- ptr += 5 * enc->minBytesPerChar;
- end -= 2 * enc->minBytesPerChar;
- if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
- || !name) {
- *badPtr = ptr;
- return 0;
- }
- if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
- if (!isGeneralTextEntity) {
- *badPtr = name;
- return 0;
- }
- }
- else {
- if (versionPtr)
- *versionPtr = val;
- if (versionEndPtr)
- *versionEndPtr = ptr;
- if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
- *badPtr = ptr;
- return 0;
- }
- if (!name) {
- if (isGeneralTextEntity) {
- /* a TextDecl must have an EncodingDecl */
- *badPtr = ptr;
- return 0;
- }
- return 1;
- }
- }
- if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
- int c = toAscii(enc, val, end);
- if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {
- *badPtr = val;
- return 0;
- }
- if (encodingName)
- *encodingName = val;
- if (encoding)
- *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
- if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
- *badPtr = ptr;
- return 0;
- }
- if (!name)
- return 1;
- }
- if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
- || isGeneralTextEntity) {
- *badPtr = name;
- return 0;
- }
- if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
- if (standalone)
- *standalone = 1;
- }
- else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
- if (standalone)
- *standalone = 0;
- }
- else {
- *badPtr = val;
- return 0;
- }
- while (isSpace(toAscii(enc, ptr, end)))
- ptr += enc->minBytesPerChar;
- if (ptr != end) {
- *badPtr = ptr;
- return 0;
- }
- return 1;
-}
-
-static int FASTCALL
-checkCharRefNumber(int result)
-{
- switch (result >> 8) {
- case 0xD8: case 0xD9: case 0xDA: case 0xDB:
- case 0xDC: case 0xDD: case 0xDE: case 0xDF:
- return -1;
- case 0:
- if (latin1_encoding.type[result] == BT_NONXML)
- return -1;
- break;
- case 0xFF:
- if (result == 0xFFFE || result == 0xFFFF)
- return -1;
- break;
- }
- return result;
-}
-
-int FASTCALL
-XmlUtf8Encode(int c, char *buf)
-{
- enum {
- /* minN is minimum legal resulting value for N byte sequence */
- min2 = 0x80,
- min3 = 0x800,
- min4 = 0x10000
- };
-
- if (c < 0)
- return 0;
- if (c < min2) {
- buf[0] = (char)(c | UTF8_cval1);
- return 1;
- }
- if (c < min3) {
- buf[0] = (char)((c >> 6) | UTF8_cval2);
- buf[1] = (char)((c & 0x3f) | 0x80);
- return 2;
- }
- if (c < min4) {
- buf[0] = (char)((c >> 12) | UTF8_cval3);
- buf[1] = (char)(((c >> 6) & 0x3f) | 0x80);
- buf[2] = (char)((c & 0x3f) | 0x80);
- return 3;
- }
- if (c < 0x110000) {
- buf[0] = (char)((c >> 18) | UTF8_cval4);
- buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);
- buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);
- buf[3] = (char)((c & 0x3f) | 0x80);
- return 4;
- }
- return 0;
-}
-
-int FASTCALL
-XmlUtf16Encode(int charNum, unsigned short *buf)
-{
- if (charNum < 0)
- return 0;
- if (charNum < 0x10000) {
- buf[0] = (unsigned short)charNum;
- return 1;
- }
- if (charNum < 0x110000) {
- charNum -= 0x10000;
- buf[0] = (unsigned short)((charNum >> 10) + 0xD800);
- buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00);
- return 2;
- }
- return 0;
-}
-
-struct unknown_encoding {
- struct normal_encoding normal;
- CONVERTER convert;
- void *userData;
- unsigned short utf16[256];
- char utf8[256][4];
-};
-
-#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *) (enc))
-
-int
-XmlSizeOfUnknownEncoding(void)
-{
- return sizeof(struct unknown_encoding);
-}
-
-static int PTRFASTCALL
-unknown_isName(const ENCODING *enc, const char *p)
-{
- const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
- int c = uenc->convert(uenc->userData, p);
- if (c & ~0xFFFF)
- return 0;
- return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
-}
-
-static int PTRFASTCALL
-unknown_isNmstrt(const ENCODING *enc, const char *p)
-{
- const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
- int c = uenc->convert(uenc->userData, p);
- if (c & ~0xFFFF)
- return 0;
- return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
-}
-
-static int PTRFASTCALL
-unknown_isInvalid(const ENCODING *enc, const char *p)
-{
- const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
- int c = uenc->convert(uenc->userData, p);
- return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
-}
-
-static enum XML_Convert_Result PTRCALL
-unknown_toUtf8(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- char **toP, const char *toLim)
-{
- const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
- char buf[XML_UTF8_ENCODE_MAX];
- for (;;) {
- const char *utf8;
- int n;
- if (*fromP == fromLim)
- return XML_CONVERT_COMPLETED;
- utf8 = uenc->utf8[(unsigned char)**fromP];
- n = *utf8++;
- if (n == 0) {
- int c = uenc->convert(uenc->userData, *fromP);
- n = XmlUtf8Encode(c, buf);
- if (n > toLim - *toP)
- return XML_CONVERT_OUTPUT_EXHAUSTED;
- utf8 = buf;
- *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
- - (BT_LEAD2 - 2));
- }
- else {
- if (n > toLim - *toP)
- return XML_CONVERT_OUTPUT_EXHAUSTED;
- (*fromP)++;
- }
- do {
- *(*toP)++ = *utf8++;
- } while (--n != 0);
- }
-}
-
-static enum XML_Convert_Result PTRCALL
-unknown_toUtf16(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- unsigned short **toP, const unsigned short *toLim)
-{
- const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
- while (*fromP < fromLim && *toP < toLim) {
- unsigned short c = uenc->utf16[(unsigned char)**fromP];
- if (c == 0) {
- c = (unsigned short)
- uenc->convert(uenc->userData, *fromP);
- *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
- - (BT_LEAD2 - 2));
- }
- else
- (*fromP)++;
- *(*toP)++ = c;
- }
-
- if ((*toP == toLim) && (*fromP < fromLim))
- return XML_CONVERT_OUTPUT_EXHAUSTED;
- else
- return XML_CONVERT_COMPLETED;
-}
-
-ENCODING *
-XmlInitUnknownEncoding(void *mem,
- int *table,
- CONVERTER convert,
- void *userData)
-{
- int i;
- struct unknown_encoding *e = (struct unknown_encoding *)mem;
- for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
- ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
- for (i = 0; i < 128; i++)
- if (latin1_encoding.type[i] != BT_OTHER
- && latin1_encoding.type[i] != BT_NONXML
- && table[i] != i)
- return 0;
- for (i = 0; i < 256; i++) {
- int c = table[i];
- if (c == -1) {
- e->normal.type[i] = BT_MALFORM;
- /* This shouldn't really get used. */
- e->utf16[i] = 0xFFFF;
- e->utf8[i][0] = 1;
- e->utf8[i][1] = 0;
- }
- else if (c < 0) {
- if (c < -4)
- return 0;
- e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
- e->utf8[i][0] = 0;
- e->utf16[i] = 0;
- }
- else if (c < 0x80) {
- if (latin1_encoding.type[c] != BT_OTHER
- && latin1_encoding.type[c] != BT_NONXML
- && c != i)
- return 0;
- e->normal.type[i] = latin1_encoding.type[c];
- e->utf8[i][0] = 1;
- e->utf8[i][1] = (char)c;
- e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c);
- }
- else if (checkCharRefNumber(c) < 0) {
- e->normal.type[i] = BT_NONXML;
- /* This shouldn't really get used. */
- e->utf16[i] = 0xFFFF;
- e->utf8[i][0] = 1;
- e->utf8[i][1] = 0;
- }
- else {
- if (c > 0xFFFF)
- return 0;
- if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
- e->normal.type[i] = BT_NMSTRT;
- else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
- e->normal.type[i] = BT_NAME;
- else
- e->normal.type[i] = BT_OTHER;
- e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
- e->utf16[i] = (unsigned short)c;
- }
- }
- e->userData = userData;
- e->convert = convert;
- if (convert) {
- e->normal.isName2 = unknown_isName;
- e->normal.isName3 = unknown_isName;
- e->normal.isName4 = unknown_isName;
- e->normal.isNmstrt2 = unknown_isNmstrt;
- e->normal.isNmstrt3 = unknown_isNmstrt;
- e->normal.isNmstrt4 = unknown_isNmstrt;
- e->normal.isInvalid2 = unknown_isInvalid;
- e->normal.isInvalid3 = unknown_isInvalid;
- e->normal.isInvalid4 = unknown_isInvalid;
- }
- e->normal.enc.utf8Convert = unknown_toUtf8;
- e->normal.enc.utf16Convert = unknown_toUtf16;
- return &(e->normal.enc);
-}
-
-/* If this enumeration is changed, getEncodingIndex and encodings
-must also be changed. */
-enum {
- UNKNOWN_ENC = -1,
- ISO_8859_1_ENC = 0,
- US_ASCII_ENC,
- UTF_8_ENC,
- UTF_16_ENC,
- UTF_16BE_ENC,
- UTF_16LE_ENC,
- /* must match encodingNames up to here */
- NO_ENC
-};
-
-static const char KW_ISO_8859_1[] = {
- ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9,
- ASCII_MINUS, ASCII_1, '\0'
-};
-static const char KW_US_ASCII[] = {
- ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I,
- '\0'
-};
-static const char KW_UTF_8[] = {
- ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'
-};
-static const char KW_UTF_16[] = {
- ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'
-};
-static const char KW_UTF_16BE[] = {
- ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E,
- '\0'
-};
-static const char KW_UTF_16LE[] = {
- ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E,
- '\0'
-};
-
-static int FASTCALL
-getEncodingIndex(const char *name)
-{
- static const char * const encodingNames[] = {
- KW_ISO_8859_1,
- KW_US_ASCII,
- KW_UTF_8,
- KW_UTF_16,
- KW_UTF_16BE,
- KW_UTF_16LE,
- };
- int i;
- if (name == NULL)
- return NO_ENC;
- for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
- if (streqci(name, encodingNames[i]))
- return i;
- return UNKNOWN_ENC;
-}
-
-/* For binary compatibility, we store the index of the encoding
- specified at initialization in the isUtf16 member.
-*/
-
-#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
-#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
-
-/* This is what detects the encoding. encodingTable maps from
- encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of
- the external (protocol) specified encoding; state is
- XML_CONTENT_STATE if we're parsing an external text entity, and
- XML_PROLOG_STATE otherwise.
-*/
-
-
-static int
-initScan(const ENCODING * const *encodingTable,
- const INIT_ENCODING *enc,
- int state,
- const char *ptr,
- const char *end,
- const char **nextTokPtr)
-{
- const ENCODING **encPtr;
-
- if (ptr >= end)
- return XML_TOK_NONE;
- encPtr = enc->encPtr;
- if (ptr + 1 == end) {
- /* only a single byte available for auto-detection */
-#ifndef XML_DTD /* FIXME */
- /* a well-formed document entity must have more than one byte */
- if (state != XML_CONTENT_STATE)
- return XML_TOK_PARTIAL;
-#endif
- /* so we're parsing an external text entity... */
- /* if UTF-16 was externally specified, then we need at least 2 bytes */
- switch (INIT_ENC_INDEX(enc)) {
- case UTF_16_ENC:
- case UTF_16LE_ENC:
- case UTF_16BE_ENC:
- return XML_TOK_PARTIAL;
- }
- switch ((unsigned char)*ptr) {
- case 0xFE:
- case 0xFF:
- case 0xEF: /* possibly first byte of UTF-8 BOM */
- if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
- && state == XML_CONTENT_STATE)
- break;
- /* fall through */
- case 0x00:
- case 0x3C:
- return XML_TOK_PARTIAL;
- }
- }
- else {
- switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
- case 0xFEFF:
- if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
- && state == XML_CONTENT_STATE)
- break;
- *nextTokPtr = ptr + 2;
- *encPtr = encodingTable[UTF_16BE_ENC];
- return XML_TOK_BOM;
- /* 00 3C is handled in the default case */
- case 0x3C00:
- if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
- || INIT_ENC_INDEX(enc) == UTF_16_ENC)
- && state == XML_CONTENT_STATE)
- break;
- *encPtr = encodingTable[UTF_16LE_ENC];
- return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
- case 0xFFFE:
- if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
- && state == XML_CONTENT_STATE)
- break;
- *nextTokPtr = ptr + 2;
- *encPtr = encodingTable[UTF_16LE_ENC];
- return XML_TOK_BOM;
- case 0xEFBB:
- /* Maybe a UTF-8 BOM (EF BB BF) */
- /* If there's an explicitly specified (external) encoding
- of ISO-8859-1 or some flavour of UTF-16
- and this is an external text entity,
- don't look for the BOM,
- because it might be a legal data.
- */
- if (state == XML_CONTENT_STATE) {
- int e = INIT_ENC_INDEX(enc);
- if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC
- || e == UTF_16LE_ENC || e == UTF_16_ENC)
- break;
- }
- if (ptr + 2 == end)
- return XML_TOK_PARTIAL;
- if ((unsigned char)ptr[2] == 0xBF) {
- *nextTokPtr = ptr + 3;
- *encPtr = encodingTable[UTF_8_ENC];
- return XML_TOK_BOM;
- }
- break;
- default:
- if (ptr[0] == '\0') {
- /* 0 isn't a legal data character. Furthermore a document
- entity can only start with ASCII characters. So the only
- way this can fail to be big-endian UTF-16 if it it's an
- external parsed general entity that's labelled as
- UTF-16LE.
- */
- if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
- break;
- *encPtr = encodingTable[UTF_16BE_ENC];
- return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
- }
- else if (ptr[1] == '\0') {
- /* We could recover here in the case:
- - parsing an external entity
- - second byte is 0
- - no externally specified encoding
- - no encoding declaration
- by assuming UTF-16LE. But we don't, because this would mean when
- presented just with a single byte, we couldn't reliably determine
- whether we needed further bytes.
- */
- if (state == XML_CONTENT_STATE)
- break;
- *encPtr = encodingTable[UTF_16LE_ENC];
- return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
- }
- break;
- }
- }
- *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
- return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
-}
-
-
-#define NS(x) x
-#define ns(x) x
-#define XML_TOK_NS_C
-#include "xmltok_ns.c"
-#undef XML_TOK_NS_C
-#undef NS
-#undef ns
-
-#ifdef XML_NS
-
-#define NS(x) x ## NS
-#define ns(x) x ## _ns
-
-#define XML_TOK_NS_C
-#include "xmltok_ns.c"
-#undef XML_TOK_NS_C
-
-#undef NS
-#undef ns
-
-ENCODING *
-XmlInitUnknownEncodingNS(void *mem,
- int *table,
- CONVERTER convert,
- void *userData)
-{
- ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
- if (enc)
- ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
- return enc;
-}
-
-#endif /* XML_NS */
diff --git a/components/expat/library/xmltok_impl.c b/components/expat/library/xmltok_impl.c
deleted file mode 100644
index 5f779c0571..0000000000
--- a/components/expat/library/xmltok_impl.c
+++ /dev/null
@@ -1,1779 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-/* This file is included! */
-#ifdef XML_TOK_IMPL_C
-
-#ifndef IS_INVALID_CHAR
-#define IS_INVALID_CHAR(enc, ptr, n) (0)
-#endif
-
-#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
- case BT_LEAD ## n: \
- if (end - ptr < n) \
- return XML_TOK_PARTIAL_CHAR; \
- if (IS_INVALID_CHAR(enc, ptr, n)) { \
- *(nextTokPtr) = (ptr); \
- return XML_TOK_INVALID; \
- } \
- ptr += n; \
- break;
-
-#define INVALID_CASES(ptr, nextTokPtr) \
- INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
- INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
- INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
- case BT_NONXML: \
- case BT_MALFORM: \
- case BT_TRAIL: \
- *(nextTokPtr) = (ptr); \
- return XML_TOK_INVALID;
-
-#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
- case BT_LEAD ## n: \
- if (end - ptr < n) \
- return XML_TOK_PARTIAL_CHAR; \
- if (!IS_NAME_CHAR(enc, ptr, n)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID; \
- } \
- ptr += n; \
- break;
-
-#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
- case BT_NONASCII: \
- if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID; \
- } \
- case BT_NMSTRT: \
- case BT_HEX: \
- case BT_DIGIT: \
- case BT_NAME: \
- case BT_MINUS: \
- ptr += MINBPC(enc); \
- break; \
- CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
- CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
- CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
-
-#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
- case BT_LEAD ## n: \
- if (end - ptr < n) \
- return XML_TOK_PARTIAL_CHAR; \
- if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID; \
- } \
- ptr += n; \
- break;
-
-#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
- case BT_NONASCII: \
- if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID; \
- } \
- case BT_NMSTRT: \
- case BT_HEX: \
- ptr += MINBPC(enc); \
- break; \
- CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
- CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
- CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
-
-#ifndef PREFIX
-#define PREFIX(ident) ident
-#endif
-
-
-#define HAS_CHARS(enc, ptr, end, count) \
- (end - ptr >= count * MINBPC(enc))
-
-#define HAS_CHAR(enc, ptr, end) \
- HAS_CHARS(enc, ptr, end, 1)
-
-#define REQUIRE_CHARS(enc, ptr, end, count) \
- { \
- if (! HAS_CHARS(enc, ptr, end, count)) { \
- return XML_TOK_PARTIAL; \
- } \
- }
-
-#define REQUIRE_CHAR(enc, ptr, end) \
- REQUIRE_CHARS(enc, ptr, end, 1)
-
-
-/* ptr points to character following " */
- switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
- case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- /* fall through */
- case BT_S: case BT_CR: case BT_LF:
- *nextTokPtr = ptr;
- return XML_TOK_DECL_OPEN;
- case BT_NMSTRT:
- case BT_HEX:
- ptr += MINBPC(enc);
- break;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-static int PTRCALL
-PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr,
- const char *end, int *tokPtr)
-{
- int upper = 0;
- *tokPtr = XML_TOK_PI;
- if (end - ptr != MINBPC(enc)*3)
- return 1;
- switch (BYTE_TO_ASCII(enc, ptr)) {
- case ASCII_x:
- break;
- case ASCII_X:
- upper = 1;
- break;
- default:
- return 1;
- }
- ptr += MINBPC(enc);
- switch (BYTE_TO_ASCII(enc, ptr)) {
- case ASCII_m:
- break;
- case ASCII_M:
- upper = 1;
- break;
- default:
- return 1;
- }
- ptr += MINBPC(enc);
- switch (BYTE_TO_ASCII(enc, ptr)) {
- case ASCII_l:
- break;
- case ASCII_L:
- upper = 1;
- break;
- default:
- return 1;
- }
- if (upper)
- return 0;
- *tokPtr = XML_TOK_XML_DECL;
- return 1;
-}
-
-/* ptr points to character following "" */
-
-static int PTRCALL
-PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- int tok;
- const char *target = ptr;
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_S: case BT_CR: case BT_LF:
- if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- ptr += MINBPC(enc);
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
- INVALID_CASES(ptr, nextTokPtr)
- case BT_QUEST:
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- *nextTokPtr = ptr + MINBPC(enc);
- return tok;
- }
- break;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- return XML_TOK_PARTIAL;
- case BT_QUEST:
- if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- *nextTokPtr = ptr + MINBPC(enc);
- return tok;
- }
- /* fall through */
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-static int PTRCALL
-PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(enc), const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
- ASCII_T, ASCII_A, ASCII_LSQB };
- int i;
- /* CDATA[ */
- REQUIRE_CHARS(enc, ptr, end, 6);
- for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
- if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_CDATA_SECT_OPEN;
-}
-
-static int PTRCALL
-PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- if (ptr >= end)
- return XML_TOK_NONE;
- if (MINBPC(enc) > 1) {
- size_t n = end - ptr;
- if (n & (MINBPC(enc) - 1)) {
- n &= ~(MINBPC(enc) - 1);
- if (n == 0)
- return XML_TOK_PARTIAL;
- end = ptr + n;
- }
- }
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_RSQB:
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
- break;
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- ptr -= MINBPC(enc);
- break;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_CDATA_SECT_CLOSE;
- case BT_CR:
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- if (BYTE_TYPE(enc, ptr) == BT_LF)
- ptr += MINBPC(enc);
- *nextTokPtr = ptr;
- return XML_TOK_DATA_NEWLINE;
- case BT_LF:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_DATA_NEWLINE;
- INVALID_CASES(ptr, nextTokPtr)
- default:
- ptr += MINBPC(enc);
- break;
- }
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_DATA_CHARS; \
- } \
- ptr += n; \
- break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_NONXML:
- case BT_MALFORM:
- case BT_TRAIL:
- case BT_CR:
- case BT_LF:
- case BT_RSQB:
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
-}
-
-/* ptr points to character following "" */
-
-static int PTRCALL
-PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_S: case BT_CR: case BT_LF:
- for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_S: case BT_CR: case BT_LF:
- break;
- case BT_GT:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_END_TAG;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-#ifdef XML_NS
- case BT_COLON:
- /* no need to check qname syntax here,
- since end-tag must match exactly */
- ptr += MINBPC(enc);
- break;
-#endif
- case BT_GT:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_END_TAG;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "" */
-
-static int PTRCALL
-PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- if (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_DIGIT:
- case BT_HEX:
- break;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_DIGIT:
- case BT_HEX:
- break;
- case BT_SEMI:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_CHAR_REF;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "" */
-
-static int PTRCALL
-PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- if (HAS_CHAR(enc, ptr, end)) {
- if (CHAR_MATCHES(enc, ptr, ASCII_x))
- return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_DIGIT:
- break;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_DIGIT:
- break;
- case BT_SEMI:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_CHAR_REF;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "&" */
-
-static int PTRCALL
-PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_NUM:
- return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_SEMI:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_ENTITY_REF;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following first character of attribute name */
-
-static int PTRCALL
-PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
-#ifdef XML_NS
- int hadColon = 0;
-#endif
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-#ifdef XML_NS
- case BT_COLON:
- if (hadColon) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- hadColon = 1;
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- break;
-#endif
- case BT_S: case BT_CR: case BT_LF:
- for (;;) {
- int t;
-
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- t = BYTE_TYPE(enc, ptr);
- if (t == BT_EQUALS)
- break;
- switch (t) {
- case BT_S:
- case BT_LF:
- case BT_CR:
- break;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- /* fall through */
- case BT_EQUALS:
- {
- int open;
-#ifdef XML_NS
- hadColon = 0;
-#endif
- for (;;) {
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- open = BYTE_TYPE(enc, ptr);
- if (open == BT_QUOT || open == BT_APOS)
- break;
- switch (open) {
- case BT_S:
- case BT_LF:
- case BT_CR:
- break;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- ptr += MINBPC(enc);
- /* in attribute value */
- for (;;) {
- int t;
- REQUIRE_CHAR(enc, ptr, end);
- t = BYTE_TYPE(enc, ptr);
- if (t == open)
- break;
- switch (t) {
- INVALID_CASES(ptr, nextTokPtr)
- case BT_AMP:
- {
- int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
- if (tok <= 0) {
- if (tok == XML_TOK_INVALID)
- *nextTokPtr = ptr;
- return tok;
- }
- break;
- }
- case BT_LT:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_S:
- case BT_CR:
- case BT_LF:
- break;
- case BT_SOL:
- goto sol;
- case BT_GT:
- goto gt;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- /* ptr points to closing quote */
- for (;;) {
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_S: case BT_CR: case BT_LF:
- continue;
- case BT_GT:
- gt:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_START_TAG_WITH_ATTS;
- case BT_SOL:
- sol:
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- break;
- }
- break;
- }
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "<" */
-
-static int PTRCALL
-PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
-#ifdef XML_NS
- int hadColon;
-#endif
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_EXCL:
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_MINUS:
- return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_LSQB:
- return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),
- end, nextTokPtr);
- }
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- case BT_QUEST:
- return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_SOL:
- return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
-#ifdef XML_NS
- hadColon = 0;
-#endif
- /* we have a start-tag */
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-#ifdef XML_NS
- case BT_COLON:
- if (hadColon) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- hadColon = 1;
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- break;
-#endif
- case BT_S: case BT_CR: case BT_LF:
- {
- ptr += MINBPC(enc);
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_GT:
- goto gt;
- case BT_SOL:
- goto sol;
- case BT_S: case BT_CR: case BT_LF:
- ptr += MINBPC(enc);
- continue;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
- }
- return XML_TOK_PARTIAL;
- }
- case BT_GT:
- gt:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_START_TAG_NO_ATTS;
- case BT_SOL:
- sol:
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-static int PTRCALL
-PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- if (ptr >= end)
- return XML_TOK_NONE;
- if (MINBPC(enc) > 1) {
- size_t n = end - ptr;
- if (n & (MINBPC(enc) - 1)) {
- n &= ~(MINBPC(enc) - 1);
- if (n == 0)
- return XML_TOK_PARTIAL;
- end = ptr + n;
- }
- }
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_LT:
- return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_AMP:
- return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_CR:
- ptr += MINBPC(enc);
- if (! HAS_CHAR(enc, ptr, end))
- return XML_TOK_TRAILING_CR;
- if (BYTE_TYPE(enc, ptr) == BT_LF)
- ptr += MINBPC(enc);
- *nextTokPtr = ptr;
- return XML_TOK_DATA_NEWLINE;
- case BT_LF:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_DATA_NEWLINE;
- case BT_RSQB:
- ptr += MINBPC(enc);
- if (! HAS_CHAR(enc, ptr, end))
- return XML_TOK_TRAILING_RSQB;
- if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
- break;
- ptr += MINBPC(enc);
- if (! HAS_CHAR(enc, ptr, end))
- return XML_TOK_TRAILING_RSQB;
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- ptr -= MINBPC(enc);
- break;
- }
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- INVALID_CASES(ptr, nextTokPtr)
- default:
- ptr += MINBPC(enc);
- break;
- }
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_DATA_CHARS; \
- } \
- ptr += n; \
- break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_RSQB:
- if (HAS_CHARS(enc, ptr, end, 2)) {
- if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
- ptr += MINBPC(enc);
- break;
- }
- if (HAS_CHARS(enc, ptr, end, 3)) {
- if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
- ptr += MINBPC(enc);
- break;
- }
- *nextTokPtr = ptr + 2*MINBPC(enc);
- return XML_TOK_INVALID;
- }
- }
- /* fall through */
- case BT_AMP:
- case BT_LT:
- case BT_NONXML:
- case BT_MALFORM:
- case BT_TRAIL:
- case BT_CR:
- case BT_LF:
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
-}
-
-/* ptr points to character following "%" */
-
-static int PTRCALL
-PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
- *nextTokPtr = ptr;
- return XML_TOK_PERCENT;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_SEMI:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_PARAM_ENTITY_REF;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-static int PTRCALL
-PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_CR: case BT_LF: case BT_S:
- case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
- *nextTokPtr = ptr;
- return XML_TOK_POUND_NAME;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return -XML_TOK_POUND_NAME;
-}
-
-static int PTRCALL
-PREFIX(scanLit)(int open, const ENCODING *enc,
- const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- while (HAS_CHAR(enc, ptr, end)) {
- int t = BYTE_TYPE(enc, ptr);
- switch (t) {
- INVALID_CASES(ptr, nextTokPtr)
- case BT_QUOT:
- case BT_APOS:
- ptr += MINBPC(enc);
- if (t != open)
- break;
- if (! HAS_CHAR(enc, ptr, end))
- return -XML_TOK_LITERAL;
- *nextTokPtr = ptr;
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_S: case BT_CR: case BT_LF:
- case BT_GT: case BT_PERCNT: case BT_LSQB:
- return XML_TOK_LITERAL;
- default:
- return XML_TOK_INVALID;
- }
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-static int PTRCALL
-PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- int tok;
- if (ptr >= end)
- return XML_TOK_NONE;
- if (MINBPC(enc) > 1) {
- size_t n = end - ptr;
- if (n & (MINBPC(enc) - 1)) {
- n &= ~(MINBPC(enc) - 1);
- if (n == 0)
- return XML_TOK_PARTIAL;
- end = ptr + n;
- }
- }
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_QUOT:
- return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_APOS:
- return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_LT:
- {
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_EXCL:
- return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_QUEST:
- return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_NMSTRT:
- case BT_HEX:
- case BT_NONASCII:
- case BT_LEAD2:
- case BT_LEAD3:
- case BT_LEAD4:
- *nextTokPtr = ptr - MINBPC(enc);
- return XML_TOK_INSTANCE_START;
- }
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- case BT_CR:
- if (ptr + MINBPC(enc) == end) {
- *nextTokPtr = end;
- /* indicate that this might be part of a CR/LF pair */
- return -XML_TOK_PROLOG_S;
- }
- /* fall through */
- case BT_S: case BT_LF:
- for (;;) {
- ptr += MINBPC(enc);
- if (! HAS_CHAR(enc, ptr, end))
- break;
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_S: case BT_LF:
- break;
- case BT_CR:
- /* don't split CR/LF pair */
- if (ptr + MINBPC(enc) != end)
- break;
- /* fall through */
- default:
- *nextTokPtr = ptr;
- return XML_TOK_PROLOG_S;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_PROLOG_S;
- case BT_PERCNT:
- return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_COMMA:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_COMMA;
- case BT_LSQB:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_OPEN_BRACKET;
- case BT_RSQB:
- ptr += MINBPC(enc);
- if (! HAS_CHAR(enc, ptr, end))
- return -XML_TOK_CLOSE_BRACKET;
- if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
- REQUIRE_CHARS(enc, ptr, end, 2);
- if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
- *nextTokPtr = ptr + 2*MINBPC(enc);
- return XML_TOK_COND_SECT_CLOSE;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_CLOSE_BRACKET;
- case BT_LPAR:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_OPEN_PAREN;
- case BT_RPAR:
- ptr += MINBPC(enc);
- if (! HAS_CHAR(enc, ptr, end))
- return -XML_TOK_CLOSE_PAREN;
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_AST:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_CLOSE_PAREN_ASTERISK;
- case BT_QUEST:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_CLOSE_PAREN_QUESTION;
- case BT_PLUS:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_CLOSE_PAREN_PLUS;
- case BT_CR: case BT_LF: case BT_S:
- case BT_GT: case BT_COMMA: case BT_VERBAR:
- case BT_RPAR:
- *nextTokPtr = ptr;
- return XML_TOK_CLOSE_PAREN;
- }
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- case BT_VERBAR:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_OR;
- case BT_GT:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_DECL_CLOSE;
- case BT_NUM:
- return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- if (end - ptr < n) \
- return XML_TOK_PARTIAL_CHAR; \
- if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
- ptr += n; \
- tok = XML_TOK_NAME; \
- break; \
- } \
- if (IS_NAME_CHAR(enc, ptr, n)) { \
- ptr += n; \
- tok = XML_TOK_NMTOKEN; \
- break; \
- } \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_NMSTRT:
- case BT_HEX:
- tok = XML_TOK_NAME;
- ptr += MINBPC(enc);
- break;
- case BT_DIGIT:
- case BT_NAME:
- case BT_MINUS:
-#ifdef XML_NS
- case BT_COLON:
-#endif
- tok = XML_TOK_NMTOKEN;
- ptr += MINBPC(enc);
- break;
- case BT_NONASCII:
- if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
- ptr += MINBPC(enc);
- tok = XML_TOK_NAME;
- break;
- }
- if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
- ptr += MINBPC(enc);
- tok = XML_TOK_NMTOKEN;
- break;
- }
- /* fall through */
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_GT: case BT_RPAR: case BT_COMMA:
- case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
- case BT_S: case BT_CR: case BT_LF:
- *nextTokPtr = ptr;
- return tok;
-#ifdef XML_NS
- case BT_COLON:
- ptr += MINBPC(enc);
- switch (tok) {
- case XML_TOK_NAME:
- REQUIRE_CHAR(enc, ptr, end);
- tok = XML_TOK_PREFIXED_NAME;
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- default:
- tok = XML_TOK_NMTOKEN;
- break;
- }
- break;
- case XML_TOK_PREFIXED_NAME:
- tok = XML_TOK_NMTOKEN;
- break;
- }
- break;
-#endif
- case BT_PLUS:
- if (tok == XML_TOK_NMTOKEN) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_NAME_PLUS;
- case BT_AST:
- if (tok == XML_TOK_NMTOKEN) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_NAME_ASTERISK;
- case BT_QUEST:
- if (tok == XML_TOK_NMTOKEN) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_NAME_QUESTION;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return -tok;
-}
-
-static int PTRCALL
-PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- const char *start;
- if (ptr >= end)
- return XML_TOK_NONE;
- else if (! HAS_CHAR(enc, ptr, end))
- return XML_TOK_PARTIAL;
- start = ptr;
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: ptr += n; break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_AMP:
- if (ptr == start)
- return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- case BT_LT:
- /* this is for inside entity references */
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- case BT_LF:
- if (ptr == start) {
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_DATA_NEWLINE;
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- case BT_CR:
- if (ptr == start) {
- ptr += MINBPC(enc);
- if (! HAS_CHAR(enc, ptr, end))
- return XML_TOK_TRAILING_CR;
- if (BYTE_TYPE(enc, ptr) == BT_LF)
- ptr += MINBPC(enc);
- *nextTokPtr = ptr;
- return XML_TOK_DATA_NEWLINE;
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- case BT_S:
- if (ptr == start) {
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_ATTRIBUTE_VALUE_S;
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
-}
-
-static int PTRCALL
-PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- const char *start;
- if (ptr >= end)
- return XML_TOK_NONE;
- else if (! HAS_CHAR(enc, ptr, end))
- return XML_TOK_PARTIAL;
- start = ptr;
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: ptr += n; break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_AMP:
- if (ptr == start)
- return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- case BT_PERCNT:
- if (ptr == start) {
- int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
- end, nextTokPtr);
- return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- case BT_LF:
- if (ptr == start) {
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_DATA_NEWLINE;
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- case BT_CR:
- if (ptr == start) {
- ptr += MINBPC(enc);
- if (! HAS_CHAR(enc, ptr, end))
- return XML_TOK_TRAILING_CR;
- if (BYTE_TYPE(enc, ptr) == BT_LF)
- ptr += MINBPC(enc);
- *nextTokPtr = ptr;
- return XML_TOK_DATA_NEWLINE;
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
-}
-
-#ifdef XML_DTD
-
-static int PTRCALL
-PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- int level = 0;
- if (MINBPC(enc) > 1) {
- size_t n = end - ptr;
- if (n & (MINBPC(enc) - 1)) {
- n &= ~(MINBPC(enc) - 1);
- end = ptr + n;
- }
- }
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
- INVALID_CASES(ptr, nextTokPtr)
- case BT_LT:
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
- ++level;
- ptr += MINBPC(enc);
- }
- }
- break;
- case BT_RSQB:
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- ptr += MINBPC(enc);
- if (level == 0) {
- *nextTokPtr = ptr;
- return XML_TOK_IGNORE_SECT;
- }
- --level;
- }
- }
- break;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-#endif /* XML_DTD */
-
-static int PTRCALL
-PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
- const char **badPtr)
-{
- ptr += MINBPC(enc);
- end -= MINBPC(enc);
- for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_DIGIT:
- case BT_HEX:
- case BT_MINUS:
- case BT_APOS:
- case BT_LPAR:
- case BT_RPAR:
- case BT_PLUS:
- case BT_COMMA:
- case BT_SOL:
- case BT_EQUALS:
- case BT_QUEST:
- case BT_CR:
- case BT_LF:
- case BT_SEMI:
- case BT_EXCL:
- case BT_AST:
- case BT_PERCNT:
- case BT_NUM:
-#ifdef XML_NS
- case BT_COLON:
-#endif
- break;
- case BT_S:
- if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
- *badPtr = ptr;
- return 0;
- }
- break;
- case BT_NAME:
- case BT_NMSTRT:
- if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
- break;
- default:
- switch (BYTE_TO_ASCII(enc, ptr)) {
- case 0x24: /* $ */
- case 0x40: /* @ */
- break;
- default:
- *badPtr = ptr;
- return 0;
- }
- break;
- }
- }
- return 1;
-}
-
-/* This must only be called for a well-formed start-tag or empty
- element tag. Returns the number of attributes. Pointers to the
- first attsMax attributes are stored in atts.
-*/
-
-static int PTRCALL
-PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
- int attsMax, ATTRIBUTE *atts)
-{
- enum { other, inName, inValue } state = inName;
- int nAtts = 0;
- int open = 0; /* defined when state == inValue;
- initialization just to shut up compilers */
-
- for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define START_NAME \
- if (state == other) { \
- if (nAtts < attsMax) { \
- atts[nAtts].name = ptr; \
- atts[nAtts].normalized = 1; \
- } \
- state = inName; \
- }
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_NONASCII:
- case BT_NMSTRT:
- case BT_HEX:
- START_NAME
- break;
-#undef START_NAME
- case BT_QUOT:
- if (state != inValue) {
- if (nAtts < attsMax)
- atts[nAtts].valuePtr = ptr + MINBPC(enc);
- state = inValue;
- open = BT_QUOT;
- }
- else if (open == BT_QUOT) {
- state = other;
- if (nAtts < attsMax)
- atts[nAtts].valueEnd = ptr;
- nAtts++;
- }
- break;
- case BT_APOS:
- if (state != inValue) {
- if (nAtts < attsMax)
- atts[nAtts].valuePtr = ptr + MINBPC(enc);
- state = inValue;
- open = BT_APOS;
- }
- else if (open == BT_APOS) {
- state = other;
- if (nAtts < attsMax)
- atts[nAtts].valueEnd = ptr;
- nAtts++;
- }
- break;
- case BT_AMP:
- if (nAtts < attsMax)
- atts[nAtts].normalized = 0;
- break;
- case BT_S:
- if (state == inName)
- state = other;
- else if (state == inValue
- && nAtts < attsMax
- && atts[nAtts].normalized
- && (ptr == atts[nAtts].valuePtr
- || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
- || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
- || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
- atts[nAtts].normalized = 0;
- break;
- case BT_CR: case BT_LF:
- /* This case ensures that the first attribute name is counted
- Apart from that we could just change state on the quote. */
- if (state == inName)
- state = other;
- else if (state == inValue && nAtts < attsMax)
- atts[nAtts].normalized = 0;
- break;
- case BT_GT:
- case BT_SOL:
- if (state != inValue)
- return nAtts;
- break;
- default:
- break;
- }
- }
- /* not reached */
-}
-
-static int PTRFASTCALL
-PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr)
-{
- int result = 0;
- /* skip */
- ptr += 2*MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
- for (ptr += MINBPC(enc);
- !CHAR_MATCHES(enc, ptr, ASCII_SEMI);
- ptr += MINBPC(enc)) {
- int c = BYTE_TO_ASCII(enc, ptr);
- switch (c) {
- case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
- case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
- result <<= 4;
- result |= (c - ASCII_0);
- break;
- case ASCII_A: case ASCII_B: case ASCII_C:
- case ASCII_D: case ASCII_E: case ASCII_F:
- result <<= 4;
- result += 10 + (c - ASCII_A);
- break;
- case ASCII_a: case ASCII_b: case ASCII_c:
- case ASCII_d: case ASCII_e: case ASCII_f:
- result <<= 4;
- result += 10 + (c - ASCII_a);
- break;
- }
- if (result >= 0x110000)
- return -1;
- }
- }
- else {
- for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
- int c = BYTE_TO_ASCII(enc, ptr);
- result *= 10;
- result += (c - ASCII_0);
- if (result >= 0x110000)
- return -1;
- }
- }
- return checkCharRefNumber(result);
-}
-
-static int PTRCALL
-PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr,
- const char *end)
-{
- switch ((end - ptr)/MINBPC(enc)) {
- case 2:
- if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
- switch (BYTE_TO_ASCII(enc, ptr)) {
- case ASCII_l:
- return ASCII_LT;
- case ASCII_g:
- return ASCII_GT;
- }
- }
- break;
- case 3:
- if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_p))
- return ASCII_AMP;
- }
- }
- break;
- case 4:
- switch (BYTE_TO_ASCII(enc, ptr)) {
- case ASCII_q:
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_t))
- return ASCII_QUOT;
- }
- }
- break;
- case ASCII_a:
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_p)) {
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_s))
- return ASCII_APOS;
- }
- }
- break;
- }
- }
- return 0;
-}
-
-static int PTRCALL
-PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
-{
- for (;;) {
- switch (BYTE_TYPE(enc, ptr1)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- if (*ptr1++ != *ptr2++) \
- return 0;
- LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
-#undef LEAD_CASE
- /* fall through */
- if (*ptr1++ != *ptr2++)
- return 0;
- break;
- case BT_NONASCII:
- case BT_NMSTRT:
-#ifdef XML_NS
- case BT_COLON:
-#endif
- case BT_HEX:
- case BT_DIGIT:
- case BT_NAME:
- case BT_MINUS:
- if (*ptr2++ != *ptr1++)
- return 0;
- if (MINBPC(enc) > 1) {
- if (*ptr2++ != *ptr1++)
- return 0;
- if (MINBPC(enc) > 2) {
- if (*ptr2++ != *ptr1++)
- return 0;
- if (MINBPC(enc) > 3) {
- if (*ptr2++ != *ptr1++)
- return 0;
- }
- }
- }
- break;
- default:
- if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
- return 1;
- switch (BYTE_TYPE(enc, ptr2)) {
- case BT_LEAD2:
- case BT_LEAD3:
- case BT_LEAD4:
- case BT_NONASCII:
- case BT_NMSTRT:
-#ifdef XML_NS
- case BT_COLON:
-#endif
- case BT_HEX:
- case BT_DIGIT:
- case BT_NAME:
- case BT_MINUS:
- return 0;
- default:
- return 1;
- }
- }
- }
- /* not reached */
-}
-
-static int PTRCALL
-PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1,
- const char *end1, const char *ptr2)
-{
- for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
- if (end1 - ptr1 < MINBPC(enc))
- return 0;
- if (!CHAR_MATCHES(enc, ptr1, *ptr2))
- return 0;
- }
- return ptr1 == end1;
-}
-
-static int PTRFASTCALL
-PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
-{
- const char *start = ptr;
- for (;;) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: ptr += n; break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_NONASCII:
- case BT_NMSTRT:
-#ifdef XML_NS
- case BT_COLON:
-#endif
- case BT_HEX:
- case BT_DIGIT:
- case BT_NAME:
- case BT_MINUS:
- ptr += MINBPC(enc);
- break;
- default:
- return (int)(ptr - start);
- }
- }
-}
-
-static const char * PTRFASTCALL
-PREFIX(skipS)(const ENCODING *enc, const char *ptr)
-{
- for (;;) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_LF:
- case BT_CR:
- case BT_S:
- ptr += MINBPC(enc);
- break;
- default:
- return ptr;
- }
- }
-}
-
-static void PTRCALL
-PREFIX(updatePosition)(const ENCODING *enc,
- const char *ptr,
- const char *end,
- POSITION *pos)
-{
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- ptr += n; \
- break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_LF:
- pos->columnNumber = (XML_Size)-1;
- pos->lineNumber++;
- ptr += MINBPC(enc);
- break;
- case BT_CR:
- pos->lineNumber++;
- ptr += MINBPC(enc);
- if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF)
- ptr += MINBPC(enc);
- pos->columnNumber = (XML_Size)-1;
- break;
- default:
- ptr += MINBPC(enc);
- break;
- }
- pos->columnNumber++;
- }
-}
-
-#undef DO_LEAD_CASE
-#undef MULTIBYTE_CASES
-#undef INVALID_CASES
-#undef CHECK_NAME_CASE
-#undef CHECK_NAME_CASES
-#undef CHECK_NMSTRT_CASE
-#undef CHECK_NMSTRT_CASES
-
-#endif /* XML_TOK_IMPL_C */
diff --git a/components/expat/library/xmltok_ns.c b/components/expat/library/xmltok_ns.c
deleted file mode 100644
index c3b88fdf4e..0000000000
--- a/components/expat/library/xmltok_ns.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-/* This file is included! */
-#ifdef XML_TOK_NS_C
-
-const ENCODING *
-NS(XmlGetUtf8InternalEncoding)(void)
-{
- return &ns(internal_utf8_encoding).enc;
-}
-
-const ENCODING *
-NS(XmlGetUtf16InternalEncoding)(void)
-{
-#if BYTEORDER == 1234
- return &ns(internal_little2_encoding).enc;
-#elif BYTEORDER == 4321
- return &ns(internal_big2_encoding).enc;
-#else
- const short n = 1;
- return (*(const char *)&n
- ? &ns(internal_little2_encoding).enc
- : &ns(internal_big2_encoding).enc);
-#endif
-}
-
-static const ENCODING * const NS(encodings)[] = {
- &ns(latin1_encoding).enc,
- &ns(ascii_encoding).enc,
- &ns(utf8_encoding).enc,
- &ns(big2_encoding).enc,
- &ns(big2_encoding).enc,
- &ns(little2_encoding).enc,
- &ns(utf8_encoding).enc /* NO_ENC */
-};
-
-static int PTRCALL
-NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- return initScan(NS(encodings), (const INIT_ENCODING *)enc,
- XML_PROLOG_STATE, ptr, end, nextTokPtr);
-}
-
-static int PTRCALL
-NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- return initScan(NS(encodings), (const INIT_ENCODING *)enc,
- XML_CONTENT_STATE, ptr, end, nextTokPtr);
-}
-
-int
-NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
- const char *name)
-{
- int i = getEncodingIndex(name);
- if (i == UNKNOWN_ENC)
- return 0;
- SET_INIT_ENC_INDEX(p, i);
- p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
- p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
- p->initEnc.updatePosition = initUpdatePosition;
- p->encPtr = encPtr;
- *encPtr = &(p->initEnc);
- return 1;
-}
-
-static const ENCODING *
-NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
-{
-#define ENCODING_MAX 128
- char buf[ENCODING_MAX];
- char *p = buf;
- int i;
- XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
- if (ptr != end)
- return 0;
- *p = 0;
- if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
- return enc;
- i = getEncodingIndex(buf);
- if (i == UNKNOWN_ENC)
- return 0;
- return NS(encodings)[i];
-}
-
-int
-NS(XmlParseXmlDecl)(int isGeneralTextEntity,
- const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr,
- const char **versionPtr,
- const char **versionEndPtr,
- const char **encodingName,
- const ENCODING **encoding,
- int *standalone)
-{
- return doParseXmlDecl(NS(findEncoding),
- isGeneralTextEntity,
- enc,
- ptr,
- end,
- badPtr,
- versionPtr,
- versionEndPtr,
- encodingName,
- encoding,
- standalone);
-}
-
-#endif /* XML_TOK_NS_C */
diff --git a/components/expat/port/chardata.c b/components/expat/port/chardata.c
deleted file mode 100644
index 012499bb88..0000000000
--- a/components/expat/port/chardata.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/* Copyright (c) 1998-2003 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-
- chardata.c
-*/
-
-#ifdef HAVE_EXPAT_CONFIG_H
-#include
-#endif
-#include "minicheck.h"
-
-#include